https://school.programmers.co.kr/learn/courses/30/lessons/60057
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
문제 풀이 (JAVA)
import java.util.*;
class Solution {
public int solution(String s) {
int answer = Integer.MAX_VALUE; // 최대 숫자 길이 임의로 설정
List<String> slist = new ArrayList<>(); // substring 문자열 저장 리스트
String str=""; // 글자 개수별로 나눈 문자를 저장할 변수
String nstr=""; // 새로 조립될 문자를 저장할 변수
int cnt = 1; // 문자의 개수를 세는 카운트 변수
if(s.length() == 1){ // 테스트케이스 5번 예외처리
return 1; // 글자가 1개일때에는 조건문을 돌지 않는다.
}
for(int i=1; i<s.length(); i++){ // 자를 글자 수 = i
for(int j=0; j<s.length(); j+=i){ // j는 글자수 +i 만큼 증가
if(j+i < s.length()){ // 글자열이 최대 문자길이를 안넘긴다면
str = s.substring(j,j+i); // 글자수 i 만큼 잘라서 저장
}else{ // 자를 글자열이 최대 문자길이를 넘어간다면
str = s.substring(j,s.length()); // 남은 마지막 문자까지 저장
}
slist.add(str); // 리스트에 자른 글자열 저장
}
for(int k=0; k<slist.size()-1; k++){ // k+1과 비교하므로 size()-1 까지 비교
// 리스트에 저장한 단어 문자열 i번째와 i+1번째가 같다면
if(slist.get(k).equals(slist.get(k+1))){
cnt++; // 카운트 증가 (초기 카운트=1, 따라서 2이상)
}else{ // 다음 문자열 리스트와 같지 않다면
if(cnt > 1){ // 같은 문자열 카운트가 2 이상이라면
nstr += cnt + slist.get(k); // 숫자 + 문자열 저장
}else{ // 같은 문자열 카운트가 1, 즉 없다면
nstr += slist.get(k); // k-1에서 초기화한 글자 출력
}
cnt=1; // 다음 문자열 k+1의 카운트 초기화
}
// 마지막 size-2 인덱스 처리(마지막 문자열 출력)
if((k+1) == slist.size()-1){
if(cnt > 1){
nstr += cnt + slist.get(k+1);
}else{
nstr += slist.get(k+1);
}
}
}
// 기존에 저장한 문자열의 길이보다 작다면 결과값 변경
if(answer > nstr.length()){
answer = nstr.length();
}
slist.clear(); // 리스트 초기화
nstr=""; // 문자열 초기화
cnt=1; // 카운트 변수 초기화
}
return answer;
}
}
주요 핵심 포인트
1. for문의 i는 자를 문자열의 길이를 차례로 증가시키기 위하여 사용하였다.
2. for문의 j+=i 를 선언함으로써 다음 문자열의 길이를 반복하여 자른다. j+i가 문자열의 길이를 초과하는지 여부를 판단하여 문자열을 잘랐다.
3. 자른 문자열을 리스트에 저장하여, k번째와 k+1 번째가 같다면 cnt는 1씩 증가하였고, 초기 cnt는 1로 설정하였다. 따라서 k번째와 k+1번째가 달라질 경우 cnt의 크기에 따라 2이상이면 숫자와 함께 출력, 1이면 단일 문자열로 그대로 출력하였다. 마지막에 cnt=1 로 설정 한것은 다음 문자열의 개수를 미리 설정한 것이다. 비교문은 버블 정렬과 비슷한 알고리즘이다.
4. 마지막 인덱스에 도달했을때 경우를 출력하기 위하여 마지막에 조건절을 추가하였다.
5. 새로운 nstr 문자열 길이가 기존 answer보다 작다면 answer을 변경하였다.
6. 다음 문자열을 저장하기 위하여 clear()를 사용하여 리스트를 초기화하였고, nstr , cnt 또한 초기화하였다.
개선해야할 사항
: 해당 문제를 깔끔하게 풀었다고는 할 수 없을 것 같다. 문자열의 길이가 1~1000이하였기에 중첩되는 for문에서 시간초과 오류가 나지 않았다. 문자열의 길이가 매우 크다면, 해당 로직은 분명히 시간 초과 오류를 겪을 것이다. for문을 최소화 할수 있는 방법이 있는지 탐색해보아야겠다.