크게 봤을 때, 자르자 -> 비교하자 -> (같은 문자열) 개수 세자 -> 압축하자 -> 문자열 비교해서 작은 거 찾자
이 로직이다.
자를 땐 1개씩 잘라보기 -> 2개씩 잘라보기 -> 3개씩 -> ... -> 문자열 절반길이씩 잘라보기를 위해 for문 (1)을 사용한다.
자르고 나선 무엇을 해야 하는가?
잘려진 부분 문자열 모두를 반복문으로 순회하면서 앞 혹은 뒤와 비교하면서 개수를 세면 된다.
나는 현재(i) 부분 문자열과 뒤에 있는(i+1)에 있는 부분 문자열과 비교했다.
이 때 i가 배열의 마지막 값인지 아닌지 판별해주어야 한다. (i+1) 때문에 인덱스 아웃 오븡 ㅓ 어쩌구 예외가 발생하기 때문❗
이런식으로 압축하고 나서 압축된 문자열 길이 확인하고 현 시점까지의 최소 길이와 비교해주면 된다.
압축하는 과정에서 개수 세는 과정이 이 문제의 핵심이었던 것 같다.
import java.util.*;
class Solution {
public int solution(String s) {
int answer = 0;
int minLen = s.length(); //최소 압출 길이 초기화
int len = s.length();
//1 자를 수 있는 모든 단위만큼 반복
for(int i=1;i<=s.length()/2;i++){
//배열 크기 확정 못하기 때문에 ArrayList로
ArrayList<String> tokens = new ArrayList<>();
//2-1 i단위만큼 문자열 token으로 나누기
for(int j=0;j<len;j += i){
if(j+i<len){
tokens.add(s.substring(j, j+i));
}
else{
tokens.add(s.substring(j));
}
}
//System.out.println(tokens);
String result =""; //압축한 문자열 저장
//2-2 부분 문자열 같은지 체크하고 압축 문자열 만드는 for문
int cnt = 1;
for(int z=0;z<tokens.size();z++){
if(z < tokens.size()-1){ //마지막 토큰이 아닐 때
if(tokens.get(z).equals(tokens.get(z+1))){
cnt++;
}
else{
if(cnt==1){
result += tokens.get(z); //앞과 다른 문자열이라 바로 저장
}
else{
result += cnt+""+tokens.get(z); //앞에 상수 붙여서 문자열 저장
cnt = 1; //중복 개수 초기화
}
}
}
//마지막 토큰일 때는
else{
if(cnt==1){
result += tokens.get(z); //앞과 다른 문자열이라 바로 저장
}
else{
result += Integer.toString(cnt)+tokens.get(z); //앞에 상수 붙여서 문자열 저장
}
}
}
minLen = Math.min(minLen, result.length()); //더 작은 문자열 길이 찾기
}
answer = minLen;
return answer;
}
}