문자열 s가 입력되었을 때 다음 규칙을 따라서 이 문자열을 여러 문자열로 분해하려고 합니다.
먼저 첫 글자를 읽습니다. 이 글자를 x라고 합시다.
이제 이 문자열을 왼쪽에서 오른쪽으로 읽어나가면서, x와 x가 아닌 다른 글자들이 나온 횟수를 각각 셉니다. 처음으로 두 횟수가 같아지는 순간 멈추고, 지금까지 읽은 문자열을 분리합니다.
s에서 분리한 문자열을 빼고 남은 부분에 대해서 이 과정을 반복합니다. 남은 부분이 없다면 종료합니다.
만약 두 횟수가 다른 상태에서 더 이상 읽을 글자가 없다면, 역시 지금까지 읽은 문자열을 분리하고, 종료합니다.
문자열 s가 매개변수로 주어질 때, 위 과정과 같이 문자열들로 분해하고, 분해한 문자열의 개수를 return 하는 함수 solution을 완성하세요.
1 ≤ s의 길이 ≤ 10,000
s는 영어 소문자로만 이루어져 있습니다.
s result
"banana" 3
"abracadabra" 6
"aaabbaccccabba" 3
입출력 예 #1
s="banana"인 경우 ba - na - na와 같이 분해됩니다.
입출력 예 #2
s="abracadabra"인 경우 ab - ra - ca - da - br - a와 같이 분해됩니다.
입출력 예 #3
s="aaabbaccccabba"인 경우 aaabbacc - ccab - ba와 같이 분해됩니다.
처음에 문제이해가 잘 안돼서 하나씩 뜯어보며 분석해보았다.
ex. s="banana"
`ba`
b : 1, b아님(a) : 1
`na`
n : 1, n아님(a) : 1
`na`
n : 1, n아님(a) : 1
ex. s="aaabbaccccabba"
`aaabbacc`
a : 4, a아님(b,c) : 4
`ccab`
c : 2, c아님(a,b) : 2
`ba`
b : 1, b아님(a) : 1
문자열을 배열에 쪼개 담기
배열에서 맨 앞의 문자와 나머지 문자의 갯수 세기
갯수가 같아지면 answer++하고 배열 새롭게 갱신해서 2,3 과정 반복
배열을 다 돌았는데도 갯수가 일치하지 않을 때는 배열 길이를 1로 만들어서 return하기
배열 길이가 0이면 answer를 그대로 return, 0보다 크면 남는 부분도 count해야 하므로 ++answer를 return한다.
중간에 틀렸던 반례 : "aaba"
틀렸던 이유 : 배열을 다 돌았는데도 갯수가 일치하지 않는 경우에 return a.splice(0,1)로 했었는데, 그러면 ab가 count된다.
수정 : 끝까지 다 갯수를 세도 분리할 수 없으므로 1을 return해야 하기 위해 길이를 1만 남기고 잘랐다.
function solution(s) {
let answer = 0;
let arr = s.split('');
function Split(a){
let count = [1,0];
for(let i=1;i<a.length;i++){
a[i] === a[0] ? count[0]++ : count[1]++;
if(count[0] === count[1]){
answer++;
a.splice(0,i+1);
return a;
}
}
return a.splice(0,a.length-1);
}
while(arr.length > 1){
Split(arr);
}
return arr.length > 0 ? ++answer : answer;
}
아이디어가 좋고 시간도 더 적게 걸린다.
function solution(s) {
let answer = 0;
let current;
let count = 0;
for(let i = 0; i < s.length; i++) {
if(count === 0) {
answer++;
current = s[i]
count = 1
} else {
if(current !== s[i]) count--;
else count++;
}
}
return answer;
}