<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>bright jazz music</title>
    <link>https://catnails.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Wed, 15 Apr 2026 05:34:21 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>bright jazz music</managingEditor>
    <image>
      <title>bright jazz music</title>
      <url>https://tistory1.daumcdn.net/tistory/4270495/attach/1b25e52b404d4261ae2bf1754aa38c91</url>
      <link>https://catnails.tistory.com</link>
    </image>
    <item>
      <title>프로세스</title>
      <link>https://catnails.tistory.com/596</link>
      <description>&lt;pre id=&quot;code_1769522094320&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function solution(priorities, location) {
    // 인덱스를 함께 저장 (어떤 프로세스인지 추적)
    let queue = priorities.map((priority, index) =&amp;gt; ({
        priority,
        index
    }));
    
    let executionOrder = 0;
    
    while (queue.length &amp;gt; 0) {
        const current = queue.shift(); // 큐에서 하나 꺼냄
        
        // 큐에 현재보다 높은 우선순위가 있는지 확인
        if (queue.some(item =&amp;gt; item.priority &amp;gt; current.priority)) {
            // 있으면 다시 뒤로 보냄
            queue.push(current);
        } else {
            // 없으면 실행
            executionOrder++;
            
            // 찾던 프로세스면 반환
            if (current.index === location) {
                return executionOrder;
            }
        }
    }
}
```

## 왜 당신 코드가 틀렸나

테스트 2를 보면:
- `[1, 1, 9, 1, 1, 1]`, location=0
- 당신 코드는 0번 프로세스(우선순위 1)보다 큰 게 1개(9)니까 answer=2 반환
- 실제로는: 9가 먼저 실행되고, 그 다음 나머지 1들이 순서대로 실행되므로 0번은 **5번째**

큐 동작을 무시하고 단순 카운팅만 했기 때문입니다.

## 동작 과정 (테스트 2)
```
초기: [(1,0), (1,1), (9,2), (1,3), (1,4), (1,5)]

1. (1,0) 꺼냄 &amp;rarr; 9가 더 크니 뒤로: [(1,1), (9,2), (1,3), (1,4), (1,5), (1,0)]
2. (1,1) 꺼냄 &amp;rarr; 9가 더 크니 뒤로: [(9,2), (1,3), (1,4), (1,5), (1,0), (1,1)]
3. (9,2) 꺼냄 &amp;rarr; 최고 우선순위 &amp;rarr; 실행! (1번째)
4. (1,3) 꺼냄 &amp;rarr; 다 같으니 &amp;rarr; 실행! (2번째)
5. (1,4) 꺼냄 &amp;rarr; 실행! (3번째)
6. (1,5) 꺼냄 &amp;rarr; 실행! (4번째)
7. (1,0) 꺼냄 &amp;rarr; 실행! (5번째) &amp;larr; location=0 찾음!&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Algorithm Practice/프로그래머스</category>
      <author>bright jazz music</author>
      <guid isPermaLink="true">https://catnails.tistory.com/596</guid>
      <comments>https://catnails.tistory.com/596#entry596comment</comments>
      <pubDate>Tue, 27 Jan 2026 22:55:17 +0900</pubDate>
    </item>
    <item>
      <title>올바른 괄호</title>
      <link>https://catnails.tistory.com/595</link>
      <description>&lt;pre id=&quot;code_1769429548368&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;괄호가 바르게 짝지어졌다는 것은 '(' 문자로 열렸으면 반드시 짝지어서 ')' 문자로 닫혀야 한다는 뜻입니다. 예를 들어

&quot;()()&quot; 또는 &quot;(())()&quot; 는 올바른 괄호입니다.
&quot;)()(&quot; 또는 &quot;(()(&quot; 는 올바르지 않은 괄호입니다.
'(' 또는 ')' 로만 이루어진 문자열 s가 주어졌을 때, 문자열 s가 올바른 괄호이면 true를 return 하고, 올바르지 않은 괄호이면 false를 return 하는 solution 함수를 완성해 주세요.

제한사항
문자열 s의 길이 : 100,000 이하의 자연수
문자열 s는 '(' 또는 ')' 로만 이루어져 있습니다.
입출력 예
s	answer
&quot;()()&quot;	true
&quot;(())()&quot;	true
&quot;)()(&quot;	false
&quot;(()(&quot;	false
입출력 예 설명
입출력 예 #1,2,3,4
문제의 예시와 같습니다.&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1769429531013&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function solution(s){
    const stack = [];
    
    for(const char of s) {
        if(char === '(') {
            stack.push(char);
        } else {
            if(stack.length === 0) return false;  // 닫을 게 없음
            stack.pop();
        }
    }
    
    return stack.length === 0;  // 스택이 비어있어야 함
}


// function solution(s){
//     var answer = true 
   
//     // 아래오 같이 풀면 ')('에 대응 못함
//     const obj = {};
    
//     const parenthesisStringArr = s.split('');
//     // console.log(parenthesisStringArr)
    
//     // parenthesisStringArr.forEach((e) =&amp;gt; Object.has(obj, 'e') ? )
//     parenthesisStringArr.forEach((e) =&amp;gt; obj[e] ? obj[e] += 1 : obj[e] = 1)
    
//     if(obj[&quot;(&quot;] !== obj[&quot;)&quot;] ) {
//         return false
//     }    

//     return answer;
// }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Algorithm Practice/프로그래머스</category>
      <author>bright jazz music</author>
      <guid isPermaLink="true">https://catnails.tistory.com/595</guid>
      <comments>https://catnails.tistory.com/595#entry595comment</comments>
      <pubDate>Mon, 26 Jan 2026 21:12:50 +0900</pubDate>
    </item>
    <item>
      <title>의상</title>
      <link>https://catnails.tistory.com/594</link>
      <description>&lt;pre id=&quot;code_1769080470293&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;문제 설명
코니는 매일 다른 옷을 조합하여 입는것을 좋아합니다.

예를 들어 코니가 가진 옷이 아래와 같고, 오늘 코니가 동그란 안경, 긴 코트, 파란색 티셔츠를 입었다면 다음날은 청바지를 추가로 입거나 동그란 안경 대신 검정 선글라스를 착용하거나 해야합니다.

종류	이름
얼굴	동그란 안경, 검정 선글라스
상의	파란색 티셔츠
하의	청바지
겉옷	긴 코트
코니는 각 종류별로 최대 1가지 의상만 착용할 수 있습니다. 예를 들어 위 예시의 경우 동그란 안경과 검정 선글라스를 동시에 착용할 수는 없습니다.
착용한 의상의 일부가 겹치더라도, 다른 의상이 겹치지 않거나, 혹은 의상을 추가로 더 착용한 경우에는 서로 다른 방법으로 옷을 착용한 것으로 계산합니다.
코니는 하루에 최소 한 개의 의상은 입습니다.
코니가 가진 의상들이 담긴 2차원 배열 clothes가 주어질 때 서로 다른 옷의 조합의 수를 return 하도록 solution 함수를 작성해주세요.

제한사항
clothes의 각 행은 [의상의 이름, 의상의 종류]로 이루어져 있습니다.
코니가 가진 의상의 수는 1개 이상 30개 이하입니다.
같은 이름을 가진 의상은 존재하지 않습니다.
clothes의 모든 원소는 문자열로 이루어져 있습니다.
모든 문자열의 길이는 1 이상 20 이하인 자연수이고 알파벳 소문자 또는 '_' 로만 이루어져 있습니다.
입출력 예
clothes	return
[[&quot;yellow_hat&quot;, &quot;headgear&quot;], [&quot;blue_sunglasses&quot;, &quot;eyewear&quot;], [&quot;green_turban&quot;, &quot;headgear&quot;]]	5
[[&quot;crow_mask&quot;, &quot;face&quot;], [&quot;blue_sunglasses&quot;, &quot;face&quot;], [&quot;smoky_makeup&quot;, &quot;face&quot;]]	3
입출력 예 설명
예제 #1
headgear에 해당하는 의상이 yellow_hat, green_turban이고 eyewear에 해당하는 의상이 blue_sunglasses이므로 아래와 같이 5개의 조합이 가능합니다.

1. yellow_hat
2. blue_sunglasses
3. green_turban
4. yellow_hat + blue_sunglasses
5. green_turban + blue_sunglasses
예제 #2
face에 해당하는 의상이 crow_mask, blue_sunglasses, smoky_makeup이므로 아래와 같이 3개의 조합이 가능합니다.

1. crow_mask
2. blue_sunglasses
3. smoky_makeup&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1769080390373&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function solution(clothes) {
    // 1. 종류별로 의상 개수 세기
    // Map 자료구조를 사용하여 {종류: 개수} 형태로 저장
    const clothesMap = new Map();
    
    // clothes 배열을 순회하면서 각 의상의 종류별 개수를 카운트
    for (const [name, type] of clothes) {
        // 해당 종류가 이미 있으면 기존 값에 +1, 없으면 0에 +1
        clothesMap.set(type, (clothesMap.get(type) || 0) + 1);
    }
    
    // 2. (각 종류 개수 + 1)을 모두 곱하기
    // +1을 하는 이유: 각 종류마다 &quot;해당 종류를 입지 않는 경우&quot;를 포함하기 위함
    // 예: headgear가 2개면 &amp;rarr; (선택1, 선택2, 안입음) = 3가지 경우의 수
    let answer = 1;
    
    // Map의 모든 value(의상 개수)를 순회
    for (const count of clothesMap.values()) {
        // 각 종류의 (개수 + 1)을 누적해서 곱함
        // 예: headgear(2개), eyewear(1개) &amp;rarr; 3 &amp;times; 2 = 6
        answer *= (count + 1);
    }
    
    // 3. 아무것도 안 입는 경우 제외
    // 모든 종류를 &quot;안입음&quot;으로 선택한 경우 1가지를 빼줌
    // 문제 조건: 최소 한 개의 의상은 입어야 함
    return answer - 1;
}

/* 
동작 예시:
clothes = [[&quot;yellow_hat&quot;, &quot;headgear&quot;], 
           [&quot;blue_sunglasses&quot;, &quot;eyewear&quot;], 
           [&quot;green_turban&quot;, &quot;headgear&quot;]]

1단계: clothesMap = { headgear: 2, eyewear: 1 }

2단계: answer = 1
       headgear: 1 &amp;times; (2+1) = 3
       eyewear:  3 &amp;times; (1+1) = 6

3단계: 6 - 1 = 5 (최종 답)

조합:
1. yellow_hat
2. green_turban  
3. blue_sunglasses
4. yellow_hat + blue_sunglasses
5. green_turban + blue_sunglasses
*/&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Algorithm Practice/프로그래머스</category>
      <author>bright jazz music</author>
      <guid isPermaLink="true">https://catnails.tistory.com/594</guid>
      <comments>https://catnails.tistory.com/594#entry594comment</comments>
      <pubDate>Thu, 22 Jan 2026 20:15:02 +0900</pubDate>
    </item>
    <item>
      <title>283. Move Zeroes</title>
      <link>https://catnails.tistory.com/593</link>
      <description>&lt;pre id=&quot;code_1769001646085&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Given an integer array nums, move all 0's to the end of it while maintaining the relative order of the non-zero elements.

Note that you must do this in-place without making a copy of the array.

 

Example 1:

Input: nums = [0,1,0,3,12]
Output: [1,3,12,0,0]
Example 2:

Input: nums = [0]
Output: [0]
 

Constraints:

1 &amp;lt;= nums.length &amp;lt;= 104
-231 &amp;lt;= nums[i] &amp;lt;= 231 - 1
 

Follow up: Could you minimize the total number of operations done?&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1769001614360&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/**
 Do not return anything, modify nums in-place instead.
 */
 
// 접근 방법
//Two Pointer 방식을 사용
// left 포인터: 0이 아닌 요소를 배치할 위치
// right 포인터: 배열을 순회하면서 0이 아닌 요소를 찾음

function moveZeroes(nums: number[]): void {
   let left = 0;

   for(let right = 0; right &amp;lt; nums.length; right++) {
        if(nums[right] !== 0) {
            if(left !== right) {
                [nums[left], nums[right]] = [nums[right], nums[left]]
            }
            // left는 &quot;0이 아닌 요소가 들어갈 위치&quot;를 가리킨다.
            // right는 배열을 순회하면서 계속 증가한다.
            // right가 0이 아닌 값을 만나면:
            //   1. left와 right의 위치를 바꾼다 (만약 다르다면)
            //   2. left를 증가시킨다 (다음 0이 아닌 값이 들어갈 자리로 이동)
            left++;
        }
   }

//    return nums
};



/* 아래와 같이 하는 게 풀어쓴 방식
var moveZeroes = function(nums) {
    let left = 0; // 0이 아닌 요소를 배치할 위치
    
    // 1단계: 0이 아닌 요소들을 앞으로 이동
    for (let right = 0; right &amp;lt; nums.length; right++) {
        if (nums[right] !== 0) {
            nums[left] = nums[right];
            left++;
        }
    }
    
    // 2단계: 남은 위치를 0으로 채우기
    for (let i = left; i &amp;lt; nums.length; i++) {
        nums[i] = 0;
    }
};

*/&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Algorithm Practice/LeetCode</category>
      <author>bright jazz music</author>
      <guid isPermaLink="true">https://catnails.tistory.com/593</guid>
      <comments>https://catnails.tistory.com/593#entry593comment</comments>
      <pubDate>Wed, 21 Jan 2026 22:21:47 +0900</pubDate>
    </item>
    <item>
      <title>전화번호 목록</title>
      <link>https://catnails.tistory.com/592</link>
      <description>&lt;pre id=&quot;code_1768995991786&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;문제 설명
전화번호부에 적힌 전화번호 중, 한 번호가 다른 번호의 접두어인 경우가 있는지 확인하려 합니다.
전화번호가 다음과 같을 경우, 구조대 전화번호는 영석이의 전화번호의 접두사입니다.

구조대 : 119
박준영 : 97 674 223
지영석 : 11 9552 4421
전화번호부에 적힌 전화번호를 담은 배열 phone_book 이 solution 함수의 매개변수로 주어질 때, 어떤 번호가 다른 번호의 접두어인 경우가 있으면 false를 그렇지 않으면 true를 return 하도록 solution 함수를 작성해주세요.

제한 사항
phone_book의 길이는 1 이상 1,000,000 이하입니다.
각 전화번호의 길이는 1 이상 20 이하입니다.
같은 전화번호가 중복해서 들어있지 않습니다.
입출력 예제
phone_book	return
[&quot;119&quot;, &quot;97674223&quot;, &quot;1195524421&quot;]	false
[&quot;123&quot;,&quot;456&quot;,&quot;789&quot;]	true
[&quot;12&quot;,&quot;123&quot;,&quot;1235&quot;,&quot;567&quot;,&quot;88&quot;]	false
입출력 예 설명
입출력 예 #1
앞에서 설명한 예와 같습니다.

입출력 예 #2
한 번호가 다른 번호의 접두사인 경우가 없으므로, 답은 true입니다.

입출력 예 #3
첫 번째 전화번호, &amp;ldquo;12&amp;rdquo;가 두 번째 전화번호 &amp;ldquo;123&amp;rdquo;의 접두사입니다. 따라서 답은 false입니다.&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1768995962413&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 해시를 이용한 방법(문제 의도인 것 같음)
// 먼저 set으로 집합을 만든 다음, 
// 개별 전화번호에 대해서 첫 자부터 length -1자까지 슬라이스해 가면서 hash에 있는지 확인하는 방법
// function solution(phone_book) {
//     // 먼저 집합으로 만듦
//     const hash = new Set(phone_book);
    
//     for(const phoneNo of phone_book) {
//         for(let i = 0; i &amp;lt; phoneNo.length; i++) {
//             const prefix = phoneNo.slice(0,i);
//             if(hash.has(prefix)) return false;
//         }
//     }
//     return true;
// }

// 통과는 했지만 위 방법은 O(n&amp;times;m) 루프에 slice까지 O(m)이므로 총 O(n&amp;times;m&amp;sup2;). 아래의 방법이 더 효과적인듯


function solution(phone_book) {
    // 먼저 소팅
    // 정렬하면 접두어 관계에 있는 번호들이 인접하게 배치됨
    phone_book.sort();
    
    // 현재 번호가 다음 번호의 접두어인지만 확인8
    // for(let i = 0; i &amp;lt; phone_book.length; i++) {   아래에서 +1해주기 때문에 여기서 -1 해줘야 함
    for(let i = 0; i &amp;lt; phone_book.length - 1; i++) {
        if(phone_book[i + 1].startsWith(phone_book[i])) return false;
    }
    return true;
}





// function solution(phone_book) {
//     phone_book.sort();
    
//     for(let i = 0; i &amp;lt; phone_book.length - 1; i++) {
//         // 현재 번호가 다음 번호의 접두어인지만 확인
//         if(phone_book[i + 1].startsWith(phone_book[i])) {
//             return false;
//         }
//     }
    
//     return true;
// }



// function solution(phone_book) {
    
//     // 순회하면서 ' '를 기준으로 나눈 뒤 다시 붙이기
    
//     //     phone_book.forEach((el) =&amp;gt; el.split(' ').join(''))
//     //     console.log(phone_book)
    
//     const obj = {};
//     phone_book.forEach((el) =&amp;gt; obj[el] = 1)
//     // console.log(obj)
    
//     // 그 다음 어떻게 하려고
//     // 오브젝트의 키를 순회시키면서
//     // 배열의 원소에 includes()가 있는지 확인하기 &amp;lt;- 이렇게 풀면 안됨. startsWith
    
//     for(const key of Object.keys(obj)) {
//        for(let i = 0; i &amp;lt; phone_book.length; i++) {

//            // 아래처럼 풀면 자기 자신을 포함하게 되어서 항상 false반환함
//            // 게다가 O(n2)이 돼 버려서 시간 초과됨
//            // if(phone_book[i].includes(key)) {
//            //     return false;
//            // }
           
//            // 자기 자신이 아니면서 &amp;amp;&amp;amp; 접두어인 경우
//            if(key !== phone_book[i] &amp;amp;&amp;amp; phone_book[i].startsWith(key)) {
//                return false;
//            }
           
//        }
//     }
    
//     var answer = true;
    
//     return answer;
// }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맨 아래가 원래 나의 풀이었음. 나의 사고방식의 문제는 이랬다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1768996093664&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;핵심 문제점 정리:
문제원인접두어 &amp;rarr; 포함문제를 정확히 파악하지 못함불필요한 obj자료구조 사용 목적이 불명확자기 자신 비교엣지 케이스를 고려하지 않음O(n&amp;sup2;)효율성보다 &quot;일단 동작&quot;에 집중
개선된 사고 프로세스:

문제 정의: &quot;접두어 관계 찾기&quot; &amp;rarr; startsWith 필요
자료구조 선택: 해시는 &quot;이 접두어가 존재하는가?&quot; O(1) 조회용
엣지 케이스: 자기 자신은 제외해야 함
효율성: 정렬하면 인접 비교만으로 충분

다음번엔 **&quot;이 자료구조를 왜 쓰는가?&quot;**를 먼저 생각&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Algorithm Practice/프로그래머스</category>
      <author>bright jazz music</author>
      <guid isPermaLink="true">https://catnails.tistory.com/592</guid>
      <comments>https://catnails.tistory.com/592#entry592comment</comments>
      <pubDate>Wed, 21 Jan 2026 20:48:58 +0900</pubDate>
    </item>
    <item>
      <title>같은 숫자는 싫어</title>
      <link>https://catnails.tistory.com/589</link>
      <description>&lt;pre id=&quot;code_1768910276463&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;배열 arr가 주어집니다. 배열 arr의 각 원소는 숫자 0부터 9까지로 이루어져 있습니다. 이때, 배열 arr에서 연속적으로 나타나는 숫자는 하나만 남기고 전부 제거하려고 합니다. 단, 제거된 후 남은 수들을 반환할 때는 배열 arr의 원소들의 순서를 유지해야 합니다. 예를 들면,

arr = [1, 1, 3, 3, 0, 1, 1] 이면 [1, 3, 0, 1] 을 return 합니다.
arr = [4, 4, 4, 3, 3] 이면 [4, 3] 을 return 합니다.
배열 arr에서 연속적으로 나타나는 숫자는 제거하고 남은 수들을 return 하는 solution 함수를 완성해 주세요.

제한사항
배열 arr의 크기 : 1,000,000 이하의 자연수
배열 arr의 원소의 크기 : 0보다 크거나 같고 9보다 작거나 같은 정수
입출력 예
arr	answer
[1,1,3,3,0,1,1]	[1,3,0,1]
[4,4,4,3,3]	[4,3]
입출력 예 설명
입출력 예 #1,2
문제의 예시와 같습니다.&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1768910256345&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function solution(arr){
    const resultArr = [];
    
    
    // 순회하면서 새로운 원소면 넣기
    // 다음 원소가 같으면 건너 뛰기
    // 만약 다르면 넣기
    
    let i = 0;
    // Infinity를 쓴 의도가 불분명하다는 지적있었음
    //solution([Infinity, Infinity, 1, 2])
    // 차라리 const resultArr = [arr[0]]; 이런 식으로 첫 요소는 무조건 넣고 인덱스는1부터 시작하는게 명확함
    
    // 아래와 같은 방법도 있겠지만 역시 처음에 넣어주는 게 명확함
    // for(let i = 0; i &amp;lt; arr.length; i++) {
    //     if(i === 0 || arr[i] !== arr[i-1]) {
    //         resultArr.push(arr[i]);
    //     }
    // }
    
    let el = Infinity
    
    for(let i = 0; i &amp;lt; arr.length; i++) {
        if(arr[i] !== el) {
            el = arr[i]
            resultArr.push(el);
        }
    }
    // while(i &amp;lt; arr.length) {
    //     if(arr[i] !== el) {
    //         el = arr[i]
    //         resultArr.push(el);
    //     } else {
    //          // 실수로 여기서 continue 해버리는 바람에 i++를 건너 뛰어 무한루프 돼버림
    //         continue;
    //     }
    //     i++;
    // }
    
    console.log(resultArr)
    return resultArr;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Algorithm Practice/프로그래머스</category>
      <author>bright jazz music</author>
      <guid isPermaLink="true">https://catnails.tistory.com/589</guid>
      <comments>https://catnails.tistory.com/589#entry589comment</comments>
      <pubDate>Tue, 20 Jan 2026 20:58:21 +0900</pubDate>
    </item>
    <item>
      <title>443. String Compression</title>
      <link>https://catnails.tistory.com/588</link>
      <description>&lt;pre id=&quot;code_1768828078229&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Given an array of characters chars, compress it using the following algorithm:

Begin with an empty string s. For each group of consecutive repeating characters in chars:

If the group's length is 1, append the character to s.
Otherwise, append the character followed by the group's length.
The compressed string s should not be returned separately, but instead, be stored in the input character array chars. Note that group lengths that are 10 or longer will be split into multiple characters in chars.

After you are done modifying the input array, return the new length of the array.

You must write an algorithm that uses only constant extra space.

Note: The characters in the array beyond the returned length do not matter and should be ignored.

 

Example 1:

Input: chars = [&quot;a&quot;,&quot;a&quot;,&quot;b&quot;,&quot;b&quot;,&quot;c&quot;,&quot;c&quot;,&quot;c&quot;]
Output: Return 6, and the first 6 characters of the input array should be: [&quot;a&quot;,&quot;2&quot;,&quot;b&quot;,&quot;2&quot;,&quot;c&quot;,&quot;3&quot;]
Explanation: The groups are &quot;aa&quot;, &quot;bb&quot;, and &quot;ccc&quot;. This compresses to &quot;a2b2c3&quot;.
Example 2:

Input: chars = [&quot;a&quot;]
Output: Return 1, and the first character of the input array should be: [&quot;a&quot;]
Explanation: The only group is &quot;a&quot;, which remains uncompressed since it's a single character.
Example 3:

Input: chars = [&quot;a&quot;,&quot;b&quot;,&quot;b&quot;,&quot;b&quot;,&quot;b&quot;,&quot;b&quot;,&quot;b&quot;,&quot;b&quot;,&quot;b&quot;,&quot;b&quot;,&quot;b&quot;,&quot;b&quot;,&quot;b&quot;]
Output: Return 4, and the first 4 characters of the input array should be: [&quot;a&quot;,&quot;b&quot;,&quot;1&quot;,&quot;2&quot;].
Explanation: The groups are &quot;a&quot; and &quot;bbbbbbbbbbbb&quot;. This compresses to &quot;ab12&quot;.
 

Constraints:

1 &amp;lt;= chars.length &amp;lt;= 2000
chars[i] is a lowercase English letter, uppercase English letter, digit, or symbol.&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1768828050222&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function compress(chars: string[]): number {
    // write pointer
    let write = 0;
    // read pointer
    let i = 0;

    while(i &amp;lt; chars.length) {
        // 현재 문자
        const char = chars[i];
        let count = 0;

        // 연속된 같은 문자 카운트
        // 배열 길이보다 적고, 같은 값인 경우 카운트가 올라감
        while(i &amp;lt; chars.length &amp;amp;&amp;amp; chars[i] === char) {
            count++;
            i++
        }
        
        // 끝까지 읽었거나 값이 달라져서 위의 반복문이 끝났음
        // Now that we've finished reading this group, let's write
        // 후위 증가 연산자라서 먼저 write의 현재 값을 배열의 인덱스로 사용해서 값을 할당하고 그 다음 ++ 됨.
        // 최초라면 0에 할당되고 자동으로 write가 1이 됨
        chars[write++] = char;

        // If count &amp;gt; 1, write the count as well
        if(count &amp;gt; 1) {
            const countStr = count.toString();
            // Iterate and attach stringified digits
            for(const digit of countStr) {
                // 여기도 마찬가지. 먼저 기존의 write값을 인덱스로 사용해서 값을 할당하고 그 다음 ++ 함.
                chars[write++] = digit
            }
        }
    }
    return write;
}

// function compress(chars: string[]): number {
//     // 객체에 속성으로 집어넣어서 카운팅하자
//     // 그리고 차례로 다시 배열에 집어 넣는다.
//     // 이 때, 만약 해당 문자의 개수가 1이라면 그냥 넣고, 1 초과 10미만이라면 숫자를 문자로 만들어서 넣는다.
//     // 10 이상이라면 자릿수대로 쪼개서 넣는다.
    
//     const charMap = new Map&amp;lt;string, number&amp;gt;();

//     chars.forEach((char) =&amp;gt; charMap.set(char, (charMap.get(char) || 0) + 1))

//     console.log(charMap)

//     // return [] as string[]
//     // return &amp;lt;string, number&amp;gt;[]
// };&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1768828237027&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;좋은 질문이에요! 제가 판단한 근거들:
1. 함수 시그니처 분석
typescriptfunction compress(chars: string[]): number

배열을 받는데 배열을 반환하지 않고 number를 반환 &amp;rarr; in-place 수정 암시
LeetCode에서 이런 패턴은 &quot;원본 배열 수정 + 유효 길이 반환&quot;을 의미해요

2. 문제 이름 추정

함수명이 compress &amp;rarr; 압축 문제
LeetCode 443번 &quot;String Compression&quot;과 시그니처가 정확히 일치

3. 일반적인 압축 알고리즘 특성

압축은 보통 연속된 중복을 처리 (Run-Length Encoding)
Map으로 전체 카운팅하면 순서가 깨지고 연속성을 잃어요


실제로 확인하는 방법:
문제를 제대로 파악하려면:
typescript// 예제 입력/출력을 보면 명확해져요
Input:  [&quot;a&quot;,&quot;a&quot;,&quot;b&quot;,&quot;b&quot;,&quot;c&quot;,&quot;c&quot;,&quot;c&quot;]
Output: 6  // 길이를 반환

// chars는 이렇게 변해야 함:
[&quot;a&quot;,&quot;2&quot;,&quot;b&quot;,&quot;2&quot;,&quot;c&quot;,&quot;3&quot;]
핵심 힌트들:

✅ 반환 타입이 number &amp;rarr; 길이 반환
✅ 배열을 인자로 받지만 새 배열을 안 만듦 &amp;rarr; in-place
✅ 압축 = 연속된 문자 처리

제가 문제 설명을 직접 본 게 아니라, 이런 시그니처 패턴과 일반적인 압축 알고리즘 지식으로 추론한 거예요.
혹시 문제 설명이나 예제가 있다면 확인해보시겠어요? 제 추측이 맞는지 확인할 수 있을 거예요!  &lt;/code&gt;&lt;/pre&gt;</description>
      <category>Algorithm Practice/LeetCode</category>
      <author>bright jazz music</author>
      <guid isPermaLink="true">https://catnails.tistory.com/588</guid>
      <comments>https://catnails.tistory.com/588#entry588comment</comments>
      <pubDate>Mon, 19 Jan 2026 22:08:37 +0900</pubDate>
    </item>
    <item>
      <title>폰켓몬</title>
      <link>https://catnails.tistory.com/587</link>
      <description>&lt;pre id=&quot;code_1768822216360&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;당신은 폰켓몬을 잡기 위한 오랜 여행 끝에, 홍 박사님의 연구실에 도착했습니다. 홍 박사님은 당신에게 자신의 연구실에 있는 총 N 마리의 폰켓몬 중에서 N/2마리를 가져가도 좋다고 했습니다.
홍 박사님 연구실의 폰켓몬은 종류에 따라 번호를 붙여 구분합니다. 따라서 같은 종류의 폰켓몬은 같은 번호를 가지고 있습니다. 예를 들어 연구실에 총 4마리의 폰켓몬이 있고, 각 폰켓몬의 종류 번호가 [3번, 1번, 2번, 3번]이라면 이는 3번 폰켓몬 두 마리, 1번 폰켓몬 한 마리, 2번 폰켓몬 한 마리가 있음을 나타냅니다. 이때, 4마리의 폰켓몬 중 2마리를 고르는 방법은 다음과 같이 6가지가 있습니다.

첫 번째(3번), 두 번째(1번) 폰켓몬을 선택
첫 번째(3번), 세 번째(2번) 폰켓몬을 선택
첫 번째(3번), 네 번째(3번) 폰켓몬을 선택
두 번째(1번), 세 번째(2번) 폰켓몬을 선택
두 번째(1번), 네 번째(3번) 폰켓몬을 선택
세 번째(2번), 네 번째(3번) 폰켓몬을 선택
이때, 첫 번째(3번) 폰켓몬과 네 번째(3번) 폰켓몬을 선택하는 방법은 한 종류(3번 폰켓몬 두 마리)의 폰켓몬만 가질 수 있지만, 다른 방법들은 모두 두 종류의 폰켓몬을 가질 수 있습니다. 따라서 위 예시에서 가질 수 있는 폰켓몬 종류 수의 최댓값은 2가 됩니다.
당신은 최대한 다양한 종류의 폰켓몬을 가지길 원하기 때문에, 최대한 많은 종류의 폰켓몬을 포함해서 N/2마리를 선택하려 합니다. N마리 폰켓몬의 종류 번호가 담긴 배열 nums가 매개변수로 주어질 때, N/2마리의 폰켓몬을 선택하는 방법 중, 가장 많은 종류의 폰켓몬을 선택하는 방법을 찾아, 그때의 폰켓몬 종류 번호의 개수를 return 하도록 solution 함수를 완성해주세요.

제한사항
nums는 폰켓몬의 종류 번호가 담긴 1차원 배열입니다.
nums의 길이(N)는 1 이상 10,000 이하의 자연수이며, 항상 짝수로 주어집니다.
폰켓몬의 종류 번호는 1 이상 200,000 이하의 자연수로 나타냅니다.
가장 많은 종류의 폰켓몬을 선택하는 방법이 여러 가지인 경우에도, 선택할 수 있는 폰켓몬 종류 개수의 최댓값 하나만 return 하면 됩니다.
입출력 예
nums	result
[3,1,2,3]	2
[3,3,3,2,2,4]	3
[3,3,3,2,2,2]	2
입출력 예 설명
입출력 예 #1
문제의 예시와 같습니다.

입출력 예 #2
6마리의 폰켓몬이 있으므로, 3마리의 폰켓몬을 골라야 합니다.
가장 많은 종류의 폰켓몬을 고르기 위해서는 3번 폰켓몬 한 마리, 2번 폰켓몬 한 마리, 4번 폰켓몬 한 마리를 고르면 되며, 따라서 3을 return 합니다.

입출력 예 #3
6마리의 폰켓몬이 있으므로, 3마리의 폰켓몬을 골라야 합니다.
가장 많은 종류의 폰켓몬을 고르기 위해서는 3번 폰켓몬 한 마리와 2번 폰켓몬 두 마리를 고르거나, 혹은 3번 폰켓몬 두 마리와 2번 폰켓몬 한 마리를 고르면 됩니다. 따라서 최대 고를 수 있는 폰켓몬 종류의 수는 2입니다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1768822236373&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 집합을 쓴 풀이
function solution(nums) {
    const limit = Math.floor(nums.length / 2);
    const uniqueCount = new Set(nums).size;
    
    return Math.min(uniqueCount, limit)
    
}


// 이렇게도 풀 수 있겠지만 Set을 쓴 풀이가 가장 빠름
// 여기서는 순회를 두 번 해야 하지만 Set은 한 번만 해도 됨
// 각각의 개수를 세어야 한다면 객체를 써야겠지만 중복만 없애기 때문에 Set이 효율적
// 

// function solution(nums) {
//     const limit = Math.floor(nums.length / 2);
    
//     const monsterObj = {};
//     nums.forEach((el) =&amp;gt; {
//         monsterObj[el] = (monsterObj[el] || 0) + 1;
//     });
    
//     const count = Object.keys(monsterObj).length;
    
//     return Math.min(count, limit);
// }


// // 풀어서 푼 내 풀이
// function solution(nums) {
//     // nums/2 마리를 가질 수 있음
//     // 최대한 많은 종류의 폰켓몬을 가질 수 있는 방법은
//     // nums / 2 가 limit
//     // 배열을 순회하면서 종류별로 객체에 담기
//     // 존재 -&amp;gt; 1 증가, 미존재 1 할당
    
//     // const limit = Math.floor(nums/2) : 실수로 length 빼먹음
//     const limit = Math.floor(nums.length / 2)
    
//     const monsterObj = {};
    
//     nums.forEach((el) =&amp;gt; {
//         if(monsterObj[el]) {
//             monsterObj[el] += 1;
//         } else {
//             monsterObj[el] = 1;
//         }        
//     })
    
    
    
    
//     let count = 0;
//     // for( key of Object.keys(monsterObj)) { // 변수선언 빼먹음
//     for( const key of Object.keys(monsterObj)) {
//         count++
//     }

//     if(count &amp;gt; limit) {
//         return limit
//     }else {
//         return count;
//     }

// //     var answer = 0;
// //     return answer;
// }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Algorithm Practice/프로그래머스</category>
      <author>bright jazz music</author>
      <guid isPermaLink="true">https://catnails.tistory.com/587</guid>
      <comments>https://catnails.tistory.com/587#entry587comment</comments>
      <pubDate>Mon, 19 Jan 2026 20:30:45 +0900</pubDate>
    </item>
    <item>
      <title>완주하지 못한 선수</title>
      <link>https://catnails.tistory.com/586</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/42576?language=javascript&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/42576?language=javascript&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1768727735598&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프로그래머스&quot; data-og-description=&quot;SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/42576?language=javascript&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/clz9e2/dJMb9jOgILI/n7JEC19VScSmxAEEeWFbwk/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/7t9K0/dJMb9eTJlzu/SAMxVWnmBtCnCzttxcCCJ1/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/42576?language=javascript&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/42576?language=javascript&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/clz9e2/dJMb9jOgILI/n7JEC19VScSmxAEEeWFbwk/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/7t9K0/dJMb9eTJlzu/SAMxVWnmBtCnCzttxcCCJ1/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1768727756149&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;문제 설명
수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.

마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.

제한사항
마라톤 경기에 참여한 선수의 수는 1명 이상 100,000명 이하입니다.
completion의 길이는 participant의 길이보다 1 작습니다.
참가자의 이름은 1개 이상 20개 이하의 알파벳 소문자로 이루어져 있습니다.
참가자 중에는 동명이인이 있을 수 있습니다.
입출력 예
participant	completion	return
[&quot;leo&quot;, &quot;kiki&quot;, &quot;eden&quot;]	[&quot;eden&quot;, &quot;kiki&quot;]	&quot;leo&quot;
[&quot;marina&quot;, &quot;josipa&quot;, &quot;nikola&quot;, &quot;vinko&quot;, &quot;filipa&quot;]	[&quot;josipa&quot;, &quot;filipa&quot;, &quot;marina&quot;, &quot;nikola&quot;]	&quot;vinko&quot;
[&quot;mislav&quot;, &quot;stanko&quot;, &quot;mislav&quot;, &quot;ana&quot;]	[&quot;stanko&quot;, &quot;ana&quot;, &quot;mislav&quot;]	&quot;mislav&quot;
입출력 예 설명
예제 #1
&quot;leo&quot;는 참여자 명단에는 있지만, 완주자 명단에는 없기 때문에 완주하지 못했습니다.

예제 #2
&quot;vinko&quot;는 참여자 명단에는 있지만, 완주자 명단에는 없기 때문에 완주하지 못했습니다.

예제 #3
&quot;mislav&quot;는 참여자 명단에는 두 명이 있지만, 완주자 명단에는 한 명밖에 없기 때문에 한명은 완주하지 못했습니다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1768727701671&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 맵으로 풀기 O(n)
function solution(participant, completion) {
    // participants 참가자 배열
    // completion 완주자 배열
    // 완주하지 못한 선수의 이름을 return하도록 솔루션 함수 작성
    
    const completedMap = new Map();
    let i = 0;
    
    // while 대신     for(const name of completion) 로 풀어도 간단했을 듯
    
    while(i &amp;lt; completion.length) {
        // 이렇게 하면 동명이인 처리 안 됨
        // completedMap.set(completion[i], true);
        completedMap.set(completion[i], (completedMap.get(completion[i]) || 0) + 1)
        i++;
    }
    // 아래 출력 코드를 남겨 놓으면 효율성 테스트에서 실패함.
    // console.log(completedMap)
    
    i = 0;
    
    while(i &amp;lt; participant.length) {
        const target = participant[i];
        let count = completedMap.get(target)
  
        if(!count) return target
  
        completedMap.set(target, count - 1)
        i++
    }
    
    // 안전 코드
    return '';
}


 
// // 간단한 건 배열로 푸는 것임 n log n (순회는 n 번이지만 정렬 로직 때문에 log n이 됨)
// function solution(participant, completion) {
//     participant.sort();
//     completion.sort();
//     // 만약 completion.length를 사용하면 끝까지 돌지 못하므로 오류 발생함
//     for(let i = 0; i &amp;lt; participant.length; i++) {
//         if(participant[i] !== completion[i]) return participant[i];
//     }
    
// }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Algorithm Practice/프로그래머스</category>
      <author>bright jazz music</author>
      <guid isPermaLink="true">https://catnails.tistory.com/586</guid>
      <comments>https://catnails.tistory.com/586#entry586comment</comments>
      <pubDate>Sun, 18 Jan 2026 18:16:12 +0900</pubDate>
    </item>
    <item>
      <title>334. Increasing Triplet Subsequence</title>
      <link>https://catnails.tistory.com/585</link>
      <description>&lt;pre id=&quot;code_1768656858204&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function increasingTriplet(nums: number[]): boolean {
    // first: 지금까지 본 가장 작은 값
    // second: first보다 크면서 가장 작은 값
    
    let first = Infinity;
    let second = Infinity;
    
    for(let num of nums) {
        if(num &amp;lt;= first) {
            // 더 작은 first 발견
            first = num;
        } else if(num &amp;lt;= second) {
            // first &amp;lt; num &amp;lt;= second
            // 더 나은 second 발견
            second = num;
        } else {
            // num &amp;gt; second &amp;gt; first
            // triplet 완성!
            return true;
        }
    }
    
    return false;
}


// 잘못된 접근
// function increasingTriplet(nums: number[]): boolean {
//     // 각 인덱스를 시작점으로 triplet 찾기
    
//     function seekTriplet(arr: number[], startIdx: number): boolean {
//         let count = 1;
//         let val = arr[startIdx];
        
//         for(let i = startIdx + 1; i &amp;lt; arr.length; i++) {
//             if(count === 3) return true;
//             if(arr[i] &amp;gt; val) {
//                 val = arr[i];
//                 count++;
//                 if(count === 3) return true;  // 여기서도 체크
//             }
//         }
//         return false;
//     }
    
//     // 모든 시작점 시도
//     for(let i = 0; i &amp;lt; nums.length - 2; i++) {
//         if(seekTriplet(nums, i)) {
//             return true;
//         }
//     }
    
//     return false;
// }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Algorithm Practice/LeetCode</category>
      <author>bright jazz music</author>
      <guid isPermaLink="true">https://catnails.tistory.com/585</guid>
      <comments>https://catnails.tistory.com/585#entry585comment</comments>
      <pubDate>Sat, 17 Jan 2026 22:34:50 +0900</pubDate>
    </item>
  </channel>
</rss>