알고리즘을 풀기 시작할 때 안 좋은 습관이 있었다. 그건 바로 항상 배열로 먼저 시도하는 건데 easy 문제를 풀면서 습관이 나와서 빠르게 정리하려고 한다. 물론 배열로 푸는 게 나쁘다는 건 아니다!! 그냥 최대한 map, set으로 풀려고 하기 때문이다. haha
최근 250321 LeetCode DailyQuestion 문제다.
문제는 간단하다. 문자열에서 모음인 부분을 뒤집어서 문자열을 반환하는 문제다.
내 코드는 다음과 같다. 문자열을 순회하면서 모음이 나오면 배열에 추가한다. 그리고 다시 문자열을 한번 더 순회하면서 모음이라면 모음을 추가했던 배열에 pop으로 요소를 꺼내 해당 인덱스의 요소를 바꿔준다.
var reverseVowels = function (s) {
const vowels = ['a', 'e', 'i', 'o', 'u'];
const vowelsArr = []
for (let i = 0; i < s.length; i++) {
if (vowels.includes(s[i].toLowerCase())) {
vowelsArr.push(s[i])
}
}
const strArr = s.split("")
for (let i = 0; i < s.length; i++) {
if (vowels.includes(strArr[i].toLowerCase())) {
strArr[i] = vowelsArr.pop()
}
}
return strArr.join("")
};
해당 코드도 나쁘진 않지만 더 개선할 부분들이 존재한다.
우선 나는 모음배열을 미리 만들어서 includes로 모음인지 확인했다. 지금처럼 배열이 길지 않으면 괜찮지만.. 그렇지 않다면 해당 메서드 보다는 Set으로 만들어서 has 메서드를 사용하는게 좋다.


따봉을 제일 많이 받은 코드는 다음과 같다. (투포인터)
var reverseVowels = function (s) {
let start = 0;
let end = s.length - 1;
const VOWELS = new Set(["a", "i", "u", "e", "o","A", "I", "U", "E", "O"])
const ans = [...s];
while(start < end){
if(!VOWELS.has(ans[start]))
start++;
if(!VOWELS.has(ans[end]))
end--;
if(VOWELS.has(ans[start]) && VOWELS.has(ans[end])){
const temp = ans[start];
ans[start] = ans[end];
ans[end] = temp;
start++
end--;
}
}
return ans.join("");
};
배열이 Map, Set보다 항상 안좋은건 아니지만, 여기서는 알맞게 사용했네요!
추가적으로, Map과 Set은 값을 넣거나 찾을 때, 해시 충돌을 해결하기 위해 여러가지 기법을 활용하고, 이로 인해 정말 스트릭하게 1번만 연산을 수행하는 것은 아니기 때문에, 배열을 사용하더라도 한번에 찾을 수 있는 상황이라면 배열을 사용하는게 나을수도 있어요!