2024. 4. 17. 13:58ㆍ알고리즘
문제
작년에 이어 새로운 문자열 게임이 있다. 게임의 진행 방식은 아래와 같다.
- 알파벳 소문자로 이루어진 문자열 W가 주어진다.
- 양의 정수 K가 주어진다.
- 어떤 문자를 정확히 K개를 포함하는 가장 짧은 연속 문자열의 길이를 구한다.
- 어떤 문자를 정확히 K개를 포함하고, 문자열의 첫 번째와 마지막 글자가 해당 문자로 같은 가장 긴 연속 문자열의 길이를 구한다.
위와 같은 방식으로 게임을 T회 진행한다.
입력
문자열 게임의 수 T가 주어진다. (1 ≤ T ≤ 100)
다음 줄부터 2개의 줄 동안 문자열 W와 정수 K가 주어진다. (1 ≤ K ≤ |W| ≤ 10,000)
출력
T개의 줄 동안 문자열 게임의 3번과 4번에서 구한 연속 문자열의 길이를 공백을 사이에 두고 출력한다.
만약 만족하는 연속 문자열이 없을 시 -1을 출력한다.
예제 입력 1
2
superaquatornado
2
abcdefghijklmnopqrstuvwxyz
5
예제 출력 1
4 8
-1
첫 번째 문자열에서 3번에서 구한 문자열은 aqua, 4번에서 구한 문자열은 raquator이다.
두 번째 문자열에서는 어떤 문자가 5개 포함된 문자열을 찾을 수 없으므로 -1을 출력한다.
예제 입력 2
1
abaaaba
3
예제 출력 2
3 4
🚀문제 접근
먼저 3번 조건을 충족하지 않으면 4번 조건도 충족할 수 없다. 때문에 문자열을 이루는 어떤 문자들도 k번 이상 사용되지 않았다면 -1을 반환하도록 구현한다.
1. 문자열을 순회하면서 문자가 사용된 갯수를 map 자료형에 저장한다. 이 때 인덱스 정보를 저장한다.
2. 사용된 갯수가 k 미만인 key는 map에서 제거한다. map의 size가 0이 된다면 ret에 -1을 저장한다.
3. map에 저장된 인덱스 배열을 k개씩 묶어서 문자열의 길이를 구해 strArr에 저장한다. 정확히 k개를 가지고 있어야하므로 k개씩 묶어야한다.
4. strArr을 오름차순으로 정렬한다. 그리고 맨 처음 요소와 마지막 요소를 배열로 묶어 ret에 저장한다.
5. ret를 형식에 맞게 출력한다.
🛠코드
let input = require('fs').readFileSync(0).toString().trim().split('\n');
let n = Number(input[0]);
let tests = [];
while (n) {
tests.push(input.splice(1, 2));
n--;
}
tests = tests.map(([str, k]) => [str.trim(), Number(k)]);
function solution() {
let ret = [];
for (const [str, k] of tests) {
let strArr = [];
let map = new Map();
[...str].forEach((c, idx) => {
if (map.has(c)) map.set(c, [...map.get(c), idx]);
else map.set(c, [idx]);
});
// 문자가 사용한 횟수가 k개 미만이면 map의 key를 지운다.
for (const c of map.keys()) {
if (map.get(c).length < k) map.delete(c);
}
if (map.size === 0) {
ret.push(-1);
continue;
}
// k개씩 묶어서 문자열의 길이를 구한다.
for (const c of map.keys()) {
let arr = map.get(c);
for (let i = arr.length - 1; i >= k - 1; i--) {
let j = i - k + 1;
strArr.push(arr[i] - arr[j] + 1);
}
}
// strArr 정렬 후에 0번째와 맨 마지막 요소를 ret에 넣어준다.
strArr.sort((a, b) => a - b);
ret.push([strArr[0], strArr[strArr.length - 1]]);
}
return ret.map((elem) => (Array.isArray(elem) ? elem.join(' ') : elem)).join('\n');
}
console.log(solution());
'알고리즘' 카테고리의 다른 글
빌런 호석 (백준 22251) (0) | 2024.04.18 |
---|---|
빗물 (백준 14719) (0) | 2024.04.17 |
컨베이어 벨트 위의 로봇 (백준 20055) (0) | 2024.04.17 |
로봇 청소기 (백준 14503) (1) | 2024.04.16 |
문자열 교환 (백준 1522번) (0) | 2024.04.16 |