題目描述
給定乙個字串,找出不含有重複字元的最長子串的長度。
示例 1:
輸入:"abcabcbb"輸出:3解釋:無重複字元的最長子串是"abc",其長度為 3。示例 2:
輸入:"bbbbb"輸出:1解釋:無重複字元的最長子串是"b",其長度為 1。示例 3:
輸入:"pwwkew"輸出:3解釋:無重複字元的最長子串是"wke",其長度為 3。演算法請注意,答案必須是乙個子串,"pwke"是乙個子串行而不是子串。
方法一:滑動視窗,在暴力法中,我們會反覆檢查乙個子字串是否含有有重複的字元,但這是沒有必要的。如果從索引 i 到 j−1 之間的子字串 sij 已經被檢查為沒有重複字元。我們只需要檢查 s[j] 對應的字元是否已經存在於子字串 sij 中。
要檢查乙個字元是否已經在子字串中,我們可以檢查整個子字串,這將產生乙個複雜度為 o(n^2) 的演算法,但我們可以做得更好。
通過使用 hashset 作為滑動視窗,我們可以用 o(1) 的時間來完成對字元是否在當前的子字串中的檢查。
滑動視窗是陣列/字串問題中常用的抽象概念。 視窗通常是在陣列/字串中由開始和結束索引定義的一系列元素的集合,即 [i, j)(左閉,右開)。而滑動視窗是可以將兩個邊界向某一方向「滑動」的視窗。例如,我們將 [i,j) 向右滑動 1 個元素,則它將變為 [i+1,j+1)(左閉,右開)。
回到我們的問題,我們使用 hashset 將字元儲存在當前視窗 [i,j)(最初 j=i)中。 然後我們向右側滑動索引 j,如果它不在 hashset 中,我們會繼續滑動 j。直到 s[j] 已經存在於 hashset 中。此時,我們找到的沒有重複字元的最長子字串將會以索引 i 開頭。如果我們對所有的 i 這樣做,就可以得到答案。
複雜度分析
方法二:優化的滑動視窗
上述的方法最多需要執行 2n 個步驟。事實上,它可以被進一步優化為僅需要 n 個步驟。我們可以定義字元到索引的對映,而不是使用集合來判斷乙個字元是否存在。 當我們找到重複的字元時,我們可以立即跳過該視窗。
也就是說,如果 s[j] 在 [i,j) 範圍內有與 j′ 重複的字元,我們不需要逐漸增加 i。 我們可以直接跳過 [i,j′] 範圍內的所有元素,並將 i 變為 j' + 1。
c++(假設字符集為 ascii 128)
以前的我們都沒有對字串s
所使用的字符集進行假設。
當我們知道該字符集比較小的時侯,我們可以用乙個整數陣列作為直接訪問表來替換map
。
常用的表如下所示:
class solution
count[s[i]] = i;
}return max(len, maxl);
}};
複雜度分析 LeetCode 無重複字元的最長子串
英文描述 given a string,find the length of the longest substring without repeating characters.examples given abcabcbb the answer is abc which the length i...
leetCode 無重複字元的最長子串
題目描述 給定乙個字串,找出不含有重複字元的最長子串的長度。示例 給定 abcabcbb 沒有重複字元的最長子串是 abc 那麼長度就是3。給定 bbbbb 最長的子串就是 b 長度是1。給定 pwwkew 最長子串是 wke 長度是3。請注意答案必須是乙個子串,pwke 是 子串行 而不是子串。解...
LeetCode 無重複字元的最長子串
給定乙個字串,找出不含有重複字元的最長子串的長度。示例 給定 abcabcbb 沒有重複字元的最長子串是 abc 那麼長度就是3。給定 bbbbb 最長的子串就是 b 長度是1。給定 pwwkew 最長子串是 wke 長度是3。請注意答案必須是乙個子串,pwke 是 子串行 而不是子串。思路 1.慢...