原版演算法在處理「字串尾部無重複字元」的情況下有 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。歡迎繼續驗證測試,共同完善。