給定一個字符串 s ,請你找出其中不含有重復字符的最長子串的長度。
示例 1:
輸入:s = "abcabcbb"
輸出:3
解釋:因為無重復字符的最長子串是 "abc",所以其長度為 3。
示例 2:
輸入:s = "bbbbb"
輸出:1
解釋:因為無重復字符的最長子串是 "b",所以其長度為 1。
示例 3:
輸入:s = "pwwkew"
輸出:3
解釋:因為無重復字符的最長子串是 "wke",所以其長度為 3。
請注意,你的答案必須是 子串 的長度,"pwke" 是一個子序列,不是子串。
答案
func lengthOfLongestSubstring(_ s: String) -> Int {
var charDict = [Character: Int]()
var maxLength = 0
var left = 0
for (index, char) in s.enumerated() {
if let lastIndex = charDict[char] {
left = max(left, lastIndex + 1)
}
charDict[char] = index
maxLength = max(maxLength, index - left + 1)
}
return maxLength
}
print(lengthOfLongestSubstring("abcabcbb"))
print(lengthOfLongestSubstring("bbbbb"))
print(lengthOfLongestSubstring("pwwkew"))
//3
//1
//3
知識點詳解:
子串和子序列的區(qū)別是:
子串:字符串中連續(xù)的字符組成的序列,比如“pwwkew”中的“wke”就是它的一個子串。
子序列:字符串中一些不一定連續(xù)的字符組成的序列,比如“pwwkew”中的“pwke”就是它的一個子序列。
子串一定是子序列,因為子串中的字符絕對是連續(xù)的。但是子序列不一定是子串,因為子序列中的字符可以不連續(xù)。
滑動窗口定義左右指針表示當前窗口范圍,右指針不斷向右滑動,根據(jù)條件收縮左指針范圍,求解最大窗口。
算法思路
- 使用字典來記錄每個字符最后一次出現(xiàn)的索引位置
- 每次嘗試擴大右邊界,檢查當前字符是否重復
- 如果重復,移動左指針到重復字符上一次索引 + 1 的位置
- 如果不重復,擴大窗口右邊界
- 不斷更新最大不重復子串長度
雙指針形成滑動窗口是解決子串問題的常用手法之一。
算法執(zhí)行過程
0.s="abcabcbb",初始化charDict = [:]
1.index = 0, s[0] = 'a', 沒重復, left = 0, charDict = ["a": 0], maxLength = 1
2.index = 1, s[1] = 'b', 沒重復, left = 0, charDict = ["b": 1, "a": 0], maxLength = 2
3.index = 2, s[2] = 'c', 沒重復, left = 0, charDict = ["b": 1, "c": 2, "a": 0], maxLength = 3
4.index = 3, s[3] = 'a', 重復, left = 1, charDict = ["b": 1, "c": 2, "a": 3], maxLength = 3
5.index = 4, s[4] = 'b', 重復, left = 2, charDict = ["b": 4, "c": 2, "a": 3], maxLength = 3
5.index = 5, s[5] = 'c', 重復, left = 3, charDict = ["b": 4, "c": 5, "a": 3], maxLength = 3
6.index = 6, s[6] = 'b', 重復, left = 5, charDict = ["b": 6, "c": 5, "a": 3], maxLength = 3
6.index = 7, s[7] = 'b', 重復, left = 7, charDict = ["b": 7, "c": 5, "a": 3], maxLength = 3
0.s="pwwkew",初始化charDict = [:]
1.index = 0, s[0] = 'p', 沒重復, left = 0, charDict = ["p": 0], maxLength = 1
2.index = 1, s[1] = 'w', 沒重復, left = 0, charDict = ["p": 0, "w": 1], maxLength = 2
3.index = 2, s[2] = 'w', 重復, left = 2, charDict = ["p": 0, "w": 2], maxLength = 2
4.index = 3, s[3] = 'k', 沒重復, left = 2, charDict = ["p": 0, "w": 2, "k": 3], maxLength = 2
5.index = 4, s[4] = 'e', 沒重復, left = 2, charDict = ["w": 2, "k": 3, "e": 4, "p": 0], maxLength = 3
5.index = 5, s[5] = 'w', 重復, left = 3, charDict = ["w": 5, "k": 3, "e": 4, "p": 0], maxLength = 3
復雜度
時間復雜度O(n),空間復雜度O(min(m, n)),其中n是字符串長度,m是字符集大小。
BTW
感謝各位簡友的寶貴時間與意見!文章難免有疏漏或錯誤,如有涉及不當之處,還望能夠提出寶貴意見。感激不盡!