49. Group Anagrams

Leetcode

題目

Given an array of strings strs, group the anagrams together. You can return the answer in any order.

An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.

解答

  • 方法一

利用 Leetcode 242. 的解答方法,再額外加判斷

var groupAnagrams = function(strs) {
    var isAnagram = function(s, t) {
        if(s.length != t.length) return false;
        const hash1 = {};
        const hash2 = {};
        for(let i=0; i<s.length; i++) {
            const value1 = s[i];
            if(hash1[value1]) hash1[value1]++;
            else hash1[value1] = 1;

            const value2 = t[i];
            if(hash2[value2]) hash2[value2]++;
            else hash2[value2] = 1;
        }

        for(let key of Object.keys(hash1)) {
            if(hash1[key] !== hash2[key]) return false;
        }
        return true;
    };
    
    const arr = []
    for(let i=0; i<strs.length; i++) {
        let isMatch = false;
        for(let j=0; j<arr.length; j++) {
            if(isAnagram(strs[i], arr[j][0])) {
                isMatch = true;
                arr[j].push(strs[i]);
                break;
            }
        }
        if(!isMatch) arr.push([strs[i]]);
    }
    return arr;
};

Time Limit Exceeded

  • 方法二 - 添加 hashCode

方法一因為使用雙迴圈運算,而且每輪都需要執行 isAnagram 判斷最終會耗時過長,所以我們額外新增一個 generateHashCode 的函式,紀錄字串進行 hashCode 後的結果,如果兩個字串 hashCode 不一樣的話就不用再執行 isAnagram 運算了

var groupAnagrams = function(strs) {
    var isAnagram = function(s, t) {
        if(s.length != t.length) return false;
        const hash1 = {};
        const hash2 = {};
        for(let i=0; i<s.length; i++) {
            const value1 = s[i];
            if(hash1[value1]) hash1[value1]++;
            else hash1[value1] = 1;

            const value2 = t[i];
            if(hash2[value2]) hash2[value2]++;
            else hash2[value2] = 1;
        }

        for(let key of Object.keys(hash1)) {
            if(hash1[key] !== hash2[key]) return false;
        }
        return true;
    };

    const generateHashCode = (str) => {
      let hashCode = 0; 
      for(let i=0; i<str.length; i++) {
        hashCode += str.charCodeAt(i);
      }
      return hashCode;
    };
    
    const arr = []
    for(let i=0; i<strs.length; i++) {
        const str = strs[i];
        const hashCode = generateHashCode(str);
        let isMatch = false;
        for(let j=0; j<arr.length; j++) {
          const target = arr[j];
          if(hashCode !== target.hashCode) continue;
          if(isAnagram(str, target.value[0])) {
              isMatch = true;
              arr[j].value.push(str);
              break;
          }
        }
        if(!isMatch) {
          arr.push({value: [str], hashCode});
        }
    }
    return arr.map(arr => arr.value);
};

Runtime: 536 ms, faster than 5.95% of JavaScript online submissions for Group Anagrams.

Memory Usage: 60.7 MB, less than 5.05% of JavaScript online submissions for Group Anagrams.

  • 方法三 - 利用內建的 sort 排序字母,當作 map 的 key

可以看到以上的方法計算的時間還是很久,為了拿空間換取時間,我們可以創建一個 hashmap,hashmap 中的 key 紀錄的是排序過的字串value 則是對應到該 排序過的字串 所在 矩陣的 index 位置

var groupAnagrams = function (strs) {
    const ans = [];
    const map = {};

    for (let i = 0; i < strs.length; i++) {
        const str = strs[i];
        const key = str.split('').sort().join('');
        const index = map[key];
        if (index !== undefined) {
            ans[index].push(str);
        } else {
            ans.push([str]);
            map[key] = ans.length - 1;
        }
    }

    return ans;
};

Runtime: 102 ms Beats 90.46% of users with JavaScript

Memory: 61.84 MB Beats 87.95% of users with JavaScript

時間複雜度:O(n) => 只遍歷 strs 矩陣一次

空間複雜度:O(n) => ans 矩陣

說明

sort 函式預設為根據字串的 Unicode 編碼位置進行排序,所以不用再傳入參數排序

'bca'.split('').sort().join('') => 'abc'

或是使用 charCodeAt 也跟上面一樣

'bca'.split('').sort((a, b) => a.charCodeAt(0) - b.charCodrAt(0)).join('') => 'abc'

相關題目

測資

let strs = ["eat","tea","tan","ate","nat","bat"];
strs = [""];
strs = ["a"];

console.log(groupAnagrams(strs))

Last updated

Was this helpful?