无重复字符的最长子串

问题:给定一个字符串 s ,请你找出其中不含有重复字符的最长子串的长度。

例如

输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

  

输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

  

输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

关于这道题,如果我们采取暴力解法,那么时间复杂度会达到O(n2),如下所示

function lengthOfLongestSubstring(s) {
    let max = 0
    if (s.length === 0 || s.length === 1) {
        return s.length
    }
    for(let i = 0; i < s.length - 1; i++) {
        let current = s[i]
        for(let j = i + 1; j < s.length; j++) {
            if (current.indexOf(s[j]) > -1) {
                break
            } else {
                current += s[j]
            }
        }
        max = current.length > max ? current.length : max
    }
    return max
}

我们可以采用滑动窗口的方法降低时间复杂度。

首先,我们定义一个map,key为字符,value为字符所在的最新位置,定义两个变量left,right。left为不重复子串开始位置,right为结束位置。如果map中有当前字符,那么需要更新left的位置。

function lengthOfLongestSubstring(s) {
    let left = 0, right = 0, max = 0
    let map = new Map()
    while(right < s.length) {
        let cur = s[right]
        if (map.has(cur)) {
            left = Math.max(map.get(cur) + 1, right)
        }
        map.set(cur, right)
        max = Math.max(right - left + 1, max)
        right++
    }
    return max
}

这样子时间复杂度就为O(n)了,是不是很有趣呢?

 

posted @ 2022-04-13 11:47  小影影  阅读(76)  评论(0)    收藏  举报