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

修正版:單次遍歷求英文字串首個最長不重複子串(含尾部邊界修復)

     編輯:關於C語言

背景

原版演算法在處理「字串尾部無重複字元」的情況下有 Bug,經網友指正後修復。核心邏輯不變,關鍵在迴圈結束後補檢查最後一個窗口。

修正後完整程式碼

char* GetSubStr(const char* str) {
    int hash[256];
    for (int i = 0; i < 256; ++i) hash[i] = -1;

    int CurrentStart = 0, MaxStart = 0, MaxEnd = 0;
    int strLen = strlen(str);

    for (int i = 0; i < strLen; ++i) {
        if (CurrentStart > hash[str[i]]) {
            hash[str[i]] = i;                 // 無重複,擴展窗口
        } else {
            int CurrentLength = i - CurrentStart;
            if (CurrentLength > MaxEnd - MaxStart) {
                MaxEnd = i;
                MaxStart = CurrentStart;
            }
            CurrentStart = hash[str[i]] + 1;  // 縮減窗口
            hash[str[i]] = i;
        }
    }

    // 【關鍵修復】檢查遍歷結束後的最後一個窗口
    if (strLen - CurrentStart > MaxEnd - MaxStart) {
        MaxEnd = strLen;
        MaxStart = CurrentStart;
    }

    int MaxLength = MaxEnd - MaxStart;
    char* reStr = new char[MaxLength + 1];
    reStr[MaxLength] = '\0';
    memcpy(reStr, str + MaxStart, MaxLength);
    return reStr;  // 呼叫端需 delete[]
}

修復邏輯解析

  • 迴圈中僅在「發現重複字元」時更新 MaxStart/MaxEnd。
  • 若字串尾部連續無重複(如 "abcde"),迴圈結束時 MaxEnd 可能仍為 0,導致回傳錯誤。
  • 補檢查 strLen - CurrentStart > MaxEnd - MaxStart,確保最後一個窗口被正確評估。

測試建議

請務必覆蓋以下用例:

  • ""(空字串)
  • "a"(單字元)
  • "aa"(全重複)
  • "abca"(中間重複)
  • "abcde"(無重複,觸發尾部修復)
  • "abcabcbb"(經典測試案例)

記憶體管理提醒

函式以 new char[] 分配記憶體,使用者必須以 delete[] 釋放。生產環境建議改為「呼叫端提供緩衝區 + 長度參數」模式,避免記憶體洩漏風險。

作者註記

作者:ifeng。歡迎繼續驗證測試,共同完善。

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