「leetcode」3.無重複字符的最長子串

原題

給定一個字符串,請你找出其中不含有重複字符的 最長子串 的長度。api

示例 1:bash

輸入: "abcabcbb"
輸出: 3 
解釋: 由於無重複字符的最長子串是 "abc",因此其長度爲 3。
複製代碼

示例 2:優化

輸入: "bbbbb"
輸出: 1
解釋: 由於無重複字符的最長子串是 "b",因此其長度爲 1。
複製代碼

示例 3:ui

輸入: "pwwkew"
輸出: 3
解釋: 由於無重複字符的最長子串是 "wke",因此其長度爲 3。
     請注意,你的答案必須是 子串 的長度,"pwke" 是一個子序列,不是子串。
複製代碼

思路

本題一樣是一道使用雙指針思路(滑動窗口)的題目。spa

咱們的startend指針初始都是指向字符串的首部,緊接着end向後移動,每向後移動一步,都須要確認startend之間的字符串是否有重複的字符。指針

使用什麼方法確認,是否有重複的字符呢?若是直接使用字符串的api, 好比indexOf,每一次查詢的時間複雜度是O(n)。咱們能夠使用hash,優化查詢的過程,每一次使用hash查詢的時間複雜度是O(1)。code

當遇到重複的字符時,說明以當前start對應的字符,開頭的最長的無重複字符的子串已經肯定了。以start字符開頭的字符已經不會有更長的無重複子串了。cdn

咱們須要將start的指針向前移動一步。而後重複上述的過程,直到end指針指向字符串的尾部結束。(已經指向尾部了,也不會有更長的子串了)blog

1.png

  1. end向前遞增 字符串

    2.png

  2. end向前遞增

    3.png

  3. 發現重複的字符。以開頭a的爲首的最長無重複字符子串,已經肯定。咱們能夠將start指針向前諾一位

    4.png

  4. end向前遞增

    4.5.png

  5. end向前遞增

    5.png

  6. ……重複上述的過程,直到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
};
複製代碼
相關文章
相關標籤/搜索