首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

字串去重演算法:四種經典解法與效能分析

     編輯:Java 程式設計入門

問題定義

給定一字串,移除其中重複字元,保留首次出現順序。例如 "zayyyy" → "zay"。

四大解法詳解

方法一:暴力雙迴圈(Brute Force)

  • 思路:外層遍歷每字元,內層檢查前方是否已出現。
  • 複雜度:時間 O(n²)、空間 O(1)。
  • 適用:極短字串、教學示範。

方法二:排序後比較

  • 思路:將字串轉字元陣列排序,相鄰比較去重。
  • 缺點:破壞原始順序,需額外記錄原索引才能還原,實務較少用。
  • 複雜度:時間 O(n log n)、空間 O(n)。

方法三:位元陣列 / 空間換時間(Bit Vector)

  • 思路:ASCII 僅 256 字元,用 256 bits(8 個 int32)記錄出現狀態。
  • 複雜度:時間 O(n)、空間 O(1)(固定 256 bits)。
  • 代碼實現(Java):
    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);
    }
    

方法四:正則表達式

  • Pattern:"(?s)(.)(?=.*\\1)"
  • 原理:正向前瞻匹配後續相同字元,替換為空串。
  • 缺點:效能較差、可讀性低、Unicode 處理易出錯。

效能與適用場景總結

方法時間複雜度空間複雜度保持順序推薦場景
暴力法O(n²)O(1)是n < 50 微小資料
排序法O(n log n)O(n)否不需保序、需排序副產出
位元陣列O(n)O(1)是ASCII 字串、高效能需求
正則O(n²) ~ O(n³)O(n)是快速原型、腳本語言

擴展:Unicode / 大字符集場景

若字串包含 Unicode 字元(超過 256),位元陣列法需改用 HashSet<Character> 或 boolean[](65536 for BMP),空間變為 O(字符集大小),但時間仍為 O(n)。

總結

「位元陣列/空間換時間」是 ASCII 字串去重的理論最優解;實務開發中,LinkedHashSet(Java)或 dict.fromkeys()(Python 3.7+)等高階 API 兼顧可讀與效能,為首選。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved