文章

Easy | Leetcode 242. Valid Anagram

Given two strings s and t, return true if t is an anagram of s, and false otherwise.


LeetCode link: 點此進入LeetCode

NeetCode link: 點此進入NeetCode

Preview Image
Easy | Leetcode 242. Valid Anagram

Question

給定兩個字串 s 和 t,如果 t 是 s 的「字母異位詞」,就回傳 true,否則回傳 false。


Solution

Solution1: Sorting

解題概念:

把兩個字串都轉成字元陣列,分別排序,排序後如果陣列完全一樣,代表是異位詞。

程式碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Solution1 {
    public static boolean isAnagram(String s, String t) {
        if (s.length() != t.length()) {
            return false;
        }

        // 將兩個字串轉換為字元陣列
        char[] s_arr = s.toCharArray();
        char[] t_arr = t.toCharArray();

        // 對兩個字元陣列進行排序
        Arrays.sort(s_arr);
        Arrays.sort(t_arr);

        // 比較兩個排序後的字元陣列是否相等
        return Arrays.equals(s_arr, t_arr);
    }
}


複雜度分析:
  • Time complexity: $O(n logn + m logm)$
    • 轉換字串成字元陣列:$O(n)$。
    • 排序陣列:$O(n log n)$。
    • 比較兩陣列是否相等:$O(n)$。
  • Space complexity: $O(n + m)$
    • 需額外兩個 char[] 陣列,長度為 n / m。

Solution2: Hash map

解題概念:

分別建立兩個 Map(count_s 和 count_t),紀錄每個字串中每個字母出現的次數;最後比較這兩個 Map 是否完全相等。

程式碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Solution2 {
    public static boolean isAnagram(String s, String t) {
        if (s.length() != t.length()) {
            return false;
        }

        // 建立兩個 HashMap,用來紀錄兩字串的字母出現次數
        Map<Character, Integer> count_s = new HashMap<Character, Integer>();
        Map<Character, Integer> count_t = new HashMap<Character, Integer>();

        // 遍歷字串 s 與 t,同步更新兩個字串的字母頻率
        for (int i = 0; i < s.length(); i++) {
            count_s.put(s.charAt(i), count_s.getOrDefault(s.charAt(i), 0) + 1);
            count_t.put(s.charAt(i), count_t.getOrDefault(s.charAt(i), 0) + 1);
        }

        // 比較兩個 HashMap 是否完全一致
        return count_s.equals(count_t);
    }
}


複雜度分析:
  • Time complexity: $O(n + m)$
    • 因為遍歷了兩個字串各一次(雖然是在同一個 for 裡處理),所以加總起來是 $O(n + m)$。
  • Space complexity: $O(1)$
    • 在英文字母小寫限定情況下,最多 26 種 → 可以視為常數 → $O(1)$。
    • 即使輸入字串很長,所需額外空間仍然不會變大。

Solution3: Hash table (using Array)

解題概念:
  • 建立一個長度為 26 的陣列 counter(英文有26個字母),用來計算每個字母出現的頻率差。
    • 每讀一個 s 的字元,就把對應的 counter +1。
    • 每讀一個 t 的字元,就把對應的 counter -1。
  • 最後遍歷整個 counter 陣列,只要有任何一個值不是 0,就代表兩字串不是異位詞。

程式碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Solution3 {
    public static boolean isAnagram(String s, String t) {
        if (s.length() != t.length()) {
            return false;
        }

        // 建立一個長度為 26 的陣列來紀錄 a~z 出現次數差異
        int[] counter = new int[26];
        for (int i = 0; i < s.length(); i++) {
            counter[s.charAt(i) - 'a']++; // 將 s 的字元出現次數 +1
            counter[t.charAt(i) - 'a']--; // 將 t 的字元出現次數 -1
        }

        // 檢查每一個字母出現次數是否都為 0
        for (int val: counter) {
            if (val != 0) {
                return false;
            }
        }

        return true;
    }
}


複雜度分析:
  • Time complexity: $O(n + m)$
    • 因為遍歷了兩個字串各一次(雖然是在同一個 for 裡處理),所以加總起來是 $O(n + m)$。
  • Space complexity: $O(1)$
    • int[] counter = new int[26],但這是 固定大小的空間,不隨輸入長度改變,所以是 $O(1)$。
本文章以 CC BY 4.0 授權

熱門標籤