문자열 교환 (백준 1522번)
2024. 4. 16. 16:14ㆍ알고리즘
문제
a와 b로만 이루어진 문자열이 주어질 때, a를 모두 연속으로 만들기 위해서 필요한 교환의 회수를 최소로 하는 프로그램을 작성하시오.
이 문자열은 원형이기 때문에, 처음과 끝은 서로 인접해 있는 것이다.
예를 들어, aabbaaabaaba이 주어졌을 때, 2번의 교환이면 a를 모두 연속으로 만들 수 있다.
입력
첫째 줄에 문자열이 주어진다. 문자열의 길이는 최대 1,000이다.
출력
첫째 줄에 필요한 교환의 회수의 최솟값을 출력한다.
예제 입력 1
abababababababa
예제 출력 1
3
예제 입력 2
ba
예제 출력 2
0
예제 입력 3
aaaabbbbba
예제 출력 3
0
예제 입력 4
abab
예제 출력 4
1
예제 입력 5
aabbaaabaaba
예제 출력 5
2
예제 입력 6
aaaa
예제 출력 6
0
🚀문제 접근
문자열이 원형이다 이런 정보때문에 원형큐 문제인지 접근하는 과정이 매우 헷갈렸다.
먼저 ababa 라는 문자열이 있다고 생각해보자.
이 문자열에서 a를 모두 연속하게 만들려면 최소 a의 갯수만큼의 영역을 확보해야한다.
위 문자열에서는 a가 세 개 있으므로 aaa 라는 size가 3인 영역을 확보해야한다는 뜻이다.
그림과 같이 3개의 영역을 확보하고 옆으로 쭉 밀면서 교환횟수를 구한다음 최솟값을 리턴하면 된다. 즉, 슬라이딩 윈도우이다.
교환횟수는 영역 안에 있는 b의 갯수이다.
🛠코드
let input = require('fs').readFileSync(0).toString().trim();
function solution() {
let ret = Number.MAX_SAFE_INTEGER;
let window = 0;
for (let i = 0; i < input.length; i++) {
if (input[i] === 'a') window++;
}
for (let i = 0; i < input.length; i++) {
let windowSize = window;
let j = i;
let cnt = 0;
while (windowSize) {
if (j >= input.length) j -= input.length;
if (input[j] === 'b') cnt++;
j++;
windowSize--;
}
if (ret > cnt) ret = cnt;
}
return ret;
}
console.log(solution());
아래 코드가 더 깔끔하게 정리가 잘 된 거 같다.
let input = require('fs').readFileSync(0).toString().trim();
function solution() {
let ret = Number.MAX_SAFE_INTEGER;
let windowSize = 0;
for (let i = 0; i < input.length; i++) {
if (input.charAt(i) === 'a') windowSize++;
}
for (let i = 0; i < input.length; i++) {
let bCount = 0;
for (let j = i; j < i + windowSize; j++) {
let idx = j % input.length;
if (input.charAt(idx) === 'b') bCount++;
}
ret = Math.min(ret, bCount);
}
return ret;
}
console.log(solution());
'알고리즘' 카테고리의 다른 글
컨베이어 벨트 위의 로봇 (백준 20055) (0) | 2024.04.17 |
---|---|
로봇 청소기 (백준 14503) (1) | 2024.04.16 |
가희와 키워드 (백준 22233번) (0) | 2024.04.16 |
영단어 암기는 괴로워 (백준 20920) (0) | 2024.04.15 |
구현 - 줄세우기 (0) | 2024.04.14 |