无重复字符的最长子串
问题:给定一个字符串 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)了,是不是很有趣呢?

浙公网安备 33010602011771号