給定一字串,移除其中重複字元,保留首次出現順序。例如 "zayyyy" → "zay"。
public static String removeDuplicate(String str) {
char[] chars = str.toCharArray();
int[] flags = new int[8]; // 8 * 32 = 256 bits
int len = chars.length;
for (int i = 0; i < len; i++) {
int idx = chars[i] / 32;
int shift = chars[i] % 32;
if ((flags[idx] & (1 << shift)) != 0) {
chars[i] = '\0'; // 標記重複
}
flags[idx] |= (1 << shift);
}
// 壓縮結果
int j = 0;
for (int i = 0; i < len; i++) {
if (chars[i] != '\0') chars[j++] = chars[i];
}
return new String(chars, 0, j);
}
"(?s)(.)(?=.*\\1)"| 方法 | 時間複雜度 | 空間複雜度 | 保持順序 | 推薦場景 |
|---|---|---|---|---|
| 暴力法 | O(n²) | O(1) | 是 | n < 50 微小資料 |
| 排序法 | O(n log n) | O(n) | 否 | 不需保序、需排序副產出 |
| 位元陣列 | O(n) | O(1) | 是 | ASCII 字串、高效能需求 |
| 正則 | O(n²) ~ O(n³) | O(n) | 是 | 快速原型、腳本語言 |
若字串包含 Unicode 字元(超過 256),位元陣列法需改用 HashSet<Character> 或 boolean[](65536 for BMP),空間變為 O(字符集大小),但時間仍為 O(n)。
「位元陣列/空間換時間」是 ASCII 字串去重的理論最優解;實務開發中,LinkedHashSet(Java)或 dict.fromkeys()(Python 3.7+)等高階 API 兼顧可讀與效能,為首選。