사이트: HackerRank
난이도: 미디움
분류: String
주어진 문자열이 유효한지 확인하는 문제이다. 문자 하나를 제거하거나 더할 때, 문자열 내 모든 문자의 개수가 동일할 경우 유효하고 그렇지 않다면 유효하지 않은 문자열이다.
aabbc
위 문자열은 c를 하나 추가하면 되기 때문에 유효한 문자열이다.
aaabbc
위 문자열은 한 문자를 추가하거나 제거해도 모두 동일한 개수를 가질 수 없기 때문에 유효하지 않은 문자열이다.
문제를 처음에 잘못 이해해서 시간을 많이 소모한 것 같다. 그리고 유효성 검사 조건문에서도 처음부터 잘 정리하지 못해 많이 헤맨것 같다.
function isValid(s) {
// Write your code here
const map = new Map();
// 문자열의 모든 문자의 개수를 기록한다.
Array.from(s).forEach(c => {
if (!map.has(c)) {
map.set(c, 1);
} else {
map.set(c, map.get(c) + 1);
}
});
// 카운팅된 문자의 개수가 3개 이상일 경우 어떤 경우에도 유효하지 않기 때문에 NO를 반환한다.
const s1 = new Set(map.values());
if (s1.size > 2) {
return 'NO';
}
const arr = [...s1.values()];
const min = Math.min(arr[0], arr[1] || Infinity);
const max = Math.max(arr[0], arr[1] || 0);
let minCount = 0, maxCount = 0;
for (let value of map.values()) {
if (value === min) {
minCount++;
}
if (value === max) {
maxCount++;
}
}
// 1. min과 max가 같은 경우 연산이 필요 없이 유효한 문자열이다.
// 2. min이 1이고 min에 해당되는 문자가 하나일 경우 하나만 제거하면 되므로 유효하다.
// 3. max이 1이고 max에 해당되는 문자가 하나일 경우 하나만 제거하면 되므로 유효하다.
// 4. max - min의 개수 차이가 1이고 각각 하나만 존재할 경우 유효한 문자열이다.
if ((min === max) ||
(min === 1 && minCount === 1) ||
(max === 1 && maxCount === 1) ||
(max - min === 1 && (minCount === 1 || maxCount === 1))) {
return 'YES';
} else {
return 'NO';
}
}
바로 풀 수 있었던 문제들은 지금은 생략하고 추후 더 효율적인 문제 풀이법을 찾아보도록 하겠다.