Valid Anagram

zoovely·2024년 5월 28일
0
post-thumbnail

💬 문제

[문제 링크]

두 문자열 s, t
t가 s의 애너그램(문자열을 재배열한 것)이라면 true
아니면 false 반환

✍️ 나의 풀이

/**
 * @param {string} s
 * @param {string} t
 * @return {boolean}
 */
var isAnagram = function(s, t) {
    if (s.length !== t.length)
        return false;

    let map = new Map();

    for (let i = 0; i < s.length; i++)
        map.set(s[i], map.has(s[i]) ? map.get(s[i]) + 1 : 1);

    for (let i = 0; i < t.length; i++) {
        let cnt = map.get(t[i]);
        if (cnt > 0) {
            map.set(t[i], cnt - 1);
        } else
            return false;
    }

    return true;
};

s와 t의 길이가 같다는 명확한 조건이 없어서 우선 둘의 길이가 다를 때 false 반환
(정확히 모든 문자를 사용하여 재배열해야 하므로 길이가 다를 수 없음)
s를 순회하면서 각 문자를 map에다가 저장, 값은 등장한 횟수
다시 t를 순회하면서 반대로 문자를 하나씩 제거
t의 문자가 map에 더 이상 없으면 바로 false 반환
무사히 순회가 끝났다면 true 반환

📌 결과

Accepted
Runtime 60ms (Beats 89.99%)
Memory 50.20MB (Beats 96.76%)

📚 러닝 포인트

여태 알고리즘을 풀어오면서 문자열 문제에서 가장 많이 사용했던 형식의 알고리즘이었기 때문에 빠르게 풀어낼 수 있었다. 그런데 두번째 for문을 처음에는 cnt가 1일 때 map에서 문자 삭제, 1 이상일 때 감소한 값으로 set, 이 외에(map에 없을 때)는 false를 반환하는 식으로 구현했다. 그런데 곰곰히 생각해보니까 그런 경우는 마지막에 map의 크기를 구하는 것처럼 한번 더 map을 살펴야할 때 필요한 거고, 이 문제에서는 for문 중간에 false로 반환되지 않으면 마지막에는 무조건 true이므로 굳이 map에서 요소를 삭제할 필요가 없었다. 즉, 1 밑으로 내려간 0과 음수들을 가진 문자는 없다고 생각하고 false를 반환하면 되는 거였다. 그래서 더 깔끔하게 코드를 작성할 수 있었다.

그리고 map.get()으로 받아온 값을 따로 변수에 저장해서 사용하는 것과 필요할 때마다 호출(고작 두번인데도!)하는 것의 런타임 속도가 꽤 차이가 나는걸 이번에도 확인할 수 있었다. 반복적으로 사용할 메소드의 결과값은 꼭 변수에 따로 할당해서 사용해보자.

profile
나도 할 수 있을까?

0개의 댓글