443. String Compression

juniping·2025년 10월 9일
post-thumbnail

🧩 문제 이해

"Chars 라는 문자 배열을 아래 규칙에 따라 '압축' 해라"

  • 빈 문자열 S에 연속적으로 반복되는 characater의 길이가 1이면 char를 append하고 그외의 경우는 (문자, 길이) 를 append 한다. (길이가 10보다 크면 길이를 쪼개서 append한다.)
  • 이때, constant extra space 만을 사용해라. (상수 공간(O(1) extra space)만 사용해야 한다.)
  • 반환 값은 기존 char 문자 배열의 새로운 길이가 되어야한다.

💡 아이디어

1️⃣ 첫 번째 접근

처음엔 Map<Character, Integer> 로 각 문자의 등장 횟수를 세는 방식을 떠올렸다.
하지만 이 문제는 “각 출현 횟수”가 아니라 “연속된 그룹”을 카운트해야 한다.

예를 들어, ['a', 'a', 'b', 'a'] 의 경우

단순 빈도수로는 a:3, b:1 이지만, 그룹으로 보면 (a,2), (b,1), (a,1) 이 되어야 한다.

→ map을 쓰면 중복된 문자가 등장했을때 연속된 카운트 위에 카운트 수가 덮어씌워진다!
따라서 Map을 사용하는건 별로 좋은 선택이 아니다.

다른 방식으로 생각해보자.

2️⃣ 두 번째 접근

  • prev : 이전 문자를 기억
  • count : 현재 문자 그룹의 길이
  • write : 압축된 결과를 덮어쓸 위치
  • 배열을 순회하며 다음 문자가 이전 문자와 같으면 count++, 다르면 지금까지의 그룹을 chars[write] 에 써넣는다.
  • 문자를 먼저 쓰고, count > 1이면 count의 각 자리수를 문자로 변환해 이어 쓴다.
  • 반복이 끝난 후에는 마지막 그룹을 따로 한 번 더 처리해준다.

🧑🏼‍💻 풀이

class Solution {
    public int compress(char[] chars) {
        char prev = chars[0];
        int count = 1;
        int write = 0;

        for(int i=1; i<chars.length; i++){
            if(chars[i]==prev){
                count++;
            }else{
                chars[write++] = prev;

                if(count>1){
                    for(char c: String.valueOf(count).toCharArray()){
                        chars[write++] = c;
                    }
                }

                count = 1;
                prev = chars[i];
            }
        }

        // 마지막 그룹 처리
        chars[write++] = prev;
        if(count>1){
                    for(char c: String.valueOf(count).toCharArray()){
                        chars[write++] = c;
                    }
        }

        return write;

    }
}

🧠 개선 포인트

첫 번째 그룹과 마지막 그룹 처리가 중복되므로, 별도 함수로 추출해도 좋을 것 같다.

profile
도전, 영원한 젊음

0개의 댓글