求字串的最長無重複字元子串(C++)
題目:
給定一個字串str,返回str的最長無重複字元子串的長度。
如:"abcd" 返回4 "abcb" 返回3
要求:若字串的長度為N 演算法的時間複雜度為O(N)。
思路:
下面給出的演算法 時間複雜度為O(N) 空間複雜度為O(M) 其中 :
N為字串的長度 M是字串中字元編碼的範圍(ASCII碼最大值)。
首先定義以下2個變數:
mp<char, int> —— 儲存某個字元最近出現的位置。
pre —— 表示遍歷到str[i]時 以str[i - 1]字元結尾的情況下最長無重複子串開始的前一個位置。
maxSubLen —— 記錄以每個字元結尾的情況下,最長無重複子串長度的最大值。
初始時 pre = -1 maxSubLen = 0
mp[str[i]] 表示遍歷完str[0]-str[i-1]後 str[i]字元最近一次出現的位置 設為A。
pre + 1 表示以str[i - 1]字元結尾的情況下 最長無重複子串的開始位置。
討論:
A > pre 以str[i]結尾的最長無重複子串範圍即為: str[A
+ 1] ~ str[i]
A <= pre 以str[i]結尾的最長無重複子串範圍即為:
str[pre + 1] ~ str[i]
令:maxEdIdx = max(A, pre);
執行完上述操作後,更新pre【pre 和 A的較大值】 更新maxSubLen【maxSubLen 和 maxEdIdx 的較大值】
重複上述操作,直至所有字元遍歷完。
貼程式碼:
<span style="font-size:12px;">#include <iostream> #include <string> using namespace std; int longestSubstring(string A, int n) { int mp[256]; memset(mp, -1, 256 * sizeof(int)); int pre = -1, maxSubLen = 0; for (int i = 0; i < n; ++i) { pre = max(pre, mp[A[i]]); maxSubLen = max(maxSubLen, i - pre); mp[A[i]] = i; } return maxSubLen; } int main(void) { string str = "aabcdb"; cout<<longestSubstring(str, str.length())<<endl; return 0; }</span>