알고리즘 풀이/프로그래머스

[level2] 프로그래머스 - 문자열 압축(JAVA)

데롱디롱 2021. 9. 1. 23:52
728x90
잘 풀리지 않아서
유튜브 해설 강의를 조금 참고해서
다시 풀어보았습니다.
https://youtu.be/HFnyxCQe_2g

 

 

- 1부터 len(문자열 길이 / 2)만큼의 길이로 잘라서 압축해 본다.

 

 

- index값을 여러개를 사용하다보니 헷갈렸는데,
   유튜브를 보니 그냥 i라는 변수를 for 밖으로 빼내서 모든 for문에 대해 사용하는 것이 안 헷갈리고 편하다.

 

- str =  i부터 i + size까지 문자열을 자른다.   => 나와 같은게 있는지 비교할 기준이 될 문자열

- new_str = size만큼 뒤로 가서 그 다음 문자열을 또 size만큼 자른다.

만약 str과 new_str이 같다면,
- i를 또 size만큼 뒤로 이동 시킨다.
- 같은 문자열이 나온 횟수를 저장하는 cnt를 증가시킨다.
- 문자열을 size크기만큼 또 자르고, 비교하는 과정(for문)을 계속 반복한다.
만약 str과 new_str이 다르다면,
- 다시 기준이 되는 문자열(str)을 현재 위치(i)부터 자른 것으로 바꿔준 뒤, 비교해야 하므로 break시켜준다.

 

 

- cnt가 0보다 크다면, 자기 자신과 같은 문자열이 있다는 것!!

- cnt + 1한 값을 문자열로 바꾸어주고 이것의 길이를 구한다.

여기서 주의할 점!!!!
aa => 2a이다. 

즉, 자신의 개수도 cnt에 포함이 되어야 한다.

이것을 간과하면, 10이어야 할 것이 9가 되어 문자열 길이가 달라지게 된다.

 

 

- sum은 현재, 문자열 s의 길이 이므로 

압축해서 사라진 문자의 길이를 빼주고
= cnt * size = 기준과 같은 문자열의 수 * 문자열의 길이
     ex) aaa 가 3a가 될때, a가 2개 사라진다.

위에서 구한 s_cnt의 길이을 더해준다.
     ex) aaa 가 3a가 될때, (cnt+1)의 값이 앞에 붙는다.

 

 

- 하지만 len이 1인 경우, 애초에 자르지 못해 for문을 돌지 않는다.
   따라서 for문 전에 len가 1이면 그냥 return 1(원래의 문자열 길이)를 리턴하도록 해주어야 한다.

 

 

class Solution {
    public int solution(String s) {
      int answer = Integer.MAX_VALUE;

        int len = s.length();

        if (len == 1) return 1;

        for (int size = 1; size <= len / 2; size++) {
            int i = 0; // index 번호
            int sum = len;

            for (; i + size <= len;) {
                String str = s.substring(i, i + size);
                i += size;

                int cnt = 0;
                for (; i + size <= len;) {
                    String new_str = s.substring(i, i + size);
                    if (str.equals(new_str)) {
                        cnt++;
                        i += size;
                    } else
                        break;
                }

                String s_cnt = (cnt + 1) + "";  // 개수는 자기자신 포함
                if (cnt > 0)
                    sum = sum - cnt * size + s_cnt.length();
            }
            answer = Math.min(answer, sum);
        }

        return answer;
    }
}