給定一個字符串,請你找出其中不含有重複字符的 最長子串 的長度。api
示例 1:bash
輸入: "abcabcbb"
輸出: 3
解釋: 由於無重複字符的最長子串是 "abc",因此其長度爲 3。
複製代碼
示例 2:優化
輸入: "bbbbb"
輸出: 1
解釋: 由於無重複字符的最長子串是 "b",因此其長度爲 1。
複製代碼
示例 3:ui
輸入: "pwwkew"
輸出: 3
解釋: 由於無重複字符的最長子串是 "wke",因此其長度爲 3。
請注意,你的答案必須是 子串 的長度,"pwke" 是一個子序列,不是子串。
複製代碼
本題一樣是一道使用雙指針思路(滑動窗口)的題目。spa
咱們的start
和end
指針初始都是指向字符串的首部,緊接着end
向後移動,每向後移動一步,都須要確認start
和end
之間的字符串是否有重複的字符。指針
使用什麼方法確認,是否有重複的字符呢?若是直接使用字符串的api, 好比indexOf
,每一次查詢的時間複雜度是O(n)。咱們能夠使用hash,優化查詢的過程,每一次使用hash查詢的時間複雜度是O(1)。code
當遇到重複的字符時,說明以當前start
對應的字符,開頭的最長的無重複字符的子串已經肯定了。以start
字符開頭的字符已經不會有更長的無重複子串了。cdn
咱們須要將start
的指針向前移動一步。而後重複上述的過程,直到end
指針指向字符串的尾部結束。(已經指向尾部了,也不會有更長的子串了)blog
end向前遞增 字符串
end向前遞增
發現重複的字符。以開頭a的爲首的最長無重複字符子串,已經肯定。咱們能夠將start指針向前諾一位
end向前遞增
end向前遞增
……重複上述的過程,直到end指向字符串的尾部,迭代結束。
/** * @param {string} s * @return {number} */
var lengthOfLongestSubstring = function(s) {
const len = s.length
const hashMap = new Map()
let start = 0
let end = 0
let max = 0
while (end < len) {
if (!hashMap.has(s[end])) {
hashMap.set(s[end], end)
max = Math.max(max, hashMap.size)
end += 1
} else {
while (start <= hashMap.get(s[end])) {
hashMap.delete(s[start])
start += 1
}
hashMap.set(s[end], end)
end += 1
}
}
return max
};
複製代碼