給定兩等長字串,判斷其是否由完全相同的字符組成(順序無關、重複次數必須一致)。例:"北京歡迎你" vs "歡迎你北京" → True;"4455" vs "4555" → False。
foreach (char c in strA) if (!strB.Contains(c)) return false;
foreach (char c in strB) if (!strA.Contains(c)) return false;
return true;
缺陷:無法檢測字符出現次數差異(如 "4455" vs "4555" 會誤判為 True)。
foreach (char c in arrA) {
if (!strB.Contains(c)) return false;
if (Count(c, arrA) != Count(c, arrB)) return false;
}
// 對 arrB 同理
雙重迴圈計數,效率隨長度增長急劇下降。
var listA = strA.ToList();
var listB = strB.ToList();
for (int i = 0; i < listA.Count; i++) {
for (int j = 0; j < listB.Count; j++) {
if (listA[i] == listB[j]) {
listA.RemoveAt(i);
listB.RemoveAt(j);
i--; j--;
break;
}
}
}
return listA.Count == 0 && listB.Count == 0;
利用配對消除思想,直觀易懂,但 RemoveAt 導致陣列位移,仍屬 O(n²)。
public static bool AreAnagrams(string a, string b) {
if (a.Length != b.Length) return false;
int[] freq = new int[65536]; // Unicode BMP 範圍
foreach (char c in a) freq[c]++;
foreach (char c in b) {
if (--freq[c] < 0) return false;
}
return true;
}
int[128] 或 int[256]。
return a.Length == b.Length &&
a.GroupBy(c => c).Select(g => new { Char = g.Key, Count = g.Count() })
.SequenceEqual(b.GroupBy(c => c).Select(g => new { Char = g.Key, Count = g.Count() }));
可讀性佳但分配大量物件,不適合高頻呼叫。
| 方法 | 時間複雜度 | 空間複雜度 | 適用場景 |
|---|---|---|---|
| 雙重 Contains | O(n²) | O(1) | 錯誤解法 |
| 逐字符計數 | O(n²) | O(1) | 短字串、教學示範 |
| List 同步移除 | O(n²) | O(n) | 短字串、邏輯直觀 |
| 頻率陣列 | O(n) | O(1) | 生產環境首選 |
| LINQ GroupBy | O(n log n) | O(n) | 原型開發、代碼簡潔優先 |
生產環境請直接使用頻率陣列法,兼具效能與正確性。