来源:力扣(LeetCode)
链接:题目链接:无重复字符的最长子串
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
问题描述
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
-
示例 1:
输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。 -
示例 2:
输入: s = “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。 -
示例 3:
输入: s = “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。 -
示例 4:
输入: s = “”
输出: 0
提示:
0 <= s.length <= 5 * 104
s 由英文字母、数字、符号和空格组成
解题思路
版本一
- 定义两个变量:最大长度 maxLen 和 临时长度 tempLen
- 遍历字符串
2.1 用当前字符和之后的字符对比,如果相同,则临时长度就是 两个元素索引的差值
2.2 对比临时长度和最大长度,如果 临时长度 > 最大长度,把临时长度赋值给最大长度
2.3 只要发现相同元素,立即退出当前循环 - 返回最大长度
注:该版本逻辑来说可行,但不具普适性。在提交代码测试时改进多次扔有问题。代码也会贴出来。有看出改进方法的可以留言给我。一起改进
版本二(滑动窗口)
原文链接:滑动窗口
这道题主要用到思路是:滑动窗口
什么是滑动窗口?
其实就是一个队列,比如例题中的 abcabcbb,进入这个队列(窗口)为 abc 满足题目要求,当再进入 a,队列变成了 abca,这时候不满足要求。所以,我们要移动这个队列!
如何移动?
我们只要把队列的左边的元素移出就行了,直到满足题目要求!
一直维持这样的队列,找出队列出现最长的长度时候,求出解!
时间复杂度:O(n)O(n)
代码示例
版本一
func lengthOfLongestSubstring(s string) int {
maxLen := 0 // 最大长度
tempLen := 0 // 临时长度
for idx1, val1 := range s {
for idx2, val2 := range s[idx1+1:] {
idx2 = idx1 + 1 + idx2
if val1 == val2 {
tempLen = idx2 - idx1
if tempLen > maxLen {
maxLen = tempLen
}
break
}
}
}
if maxLen == 0 {
maxLen = len(s)
}
return maxLen
}
版本二
func in(b int32, s []int32) bool {
for _, v := range s {
if b == v {
return true
}
}
return false
}
func lengthOfLongestSubstring(s string) int {
maxLen := 0 // 最大长度
tempLen := 0 // 临时长度
l := make([]int32, 0) // 滑动队列
for _, val := range s {
if !in(val, l) {
l = append(l, val)
tempLen = len(l)
if tempLen > maxLen {
maxLen = tempLen
}
} else {
// 把相等值之前的删除
for {
if l[0] != val {
l = l[1:]
} else {
break
}
}
l = l[1:] // 把相等值删除
l = append(l, val) // 在末尾追加新元素
tempLen = len(l)
if tempLen > maxLen {
maxLen = tempLen
}
}
}
return maxLen
}