因为是找最长的子串,意味着找一个连续的区间,那么可以考虑使用“双指针”解法。这里使用双指针的 “滑动窗口” 求解。
处理过程(这里提到的窗口就是一个子串)
- 把当前字符加入“窗口”,也就是增大窗口。
- 如果发现当前字符出现次数大于1,就不断缩小窗口,直到当前字符出现次数变成1。
- 尝试更新最大长度。
- 回到第1步继续。直到字符串遍历完。
读者可通过下面这个例子结合代码推演处理过程
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
更多细节见代码和注释(代码已提交通过)。
func lengthOfLongestSubstring(s string) int {
l := len(s)
if l < 2 {
return l
}
var (
maxLen = 1 // 最大长度
m = make(map[byte]int) // 字符->出现次数
// 双指针
i int
j int
)
// 滑动窗口
for j < l {
// 当前字符加入map,即增大窗口
b := s[j]
m[b]++
j++
for m[b] > 1 { // 出现了重复字符
// 减小窗口,直到没有重复字符为止
m[s[i]]--
i++
}
// 尝试更新最大窗口长度
if j-i > maxLen {
maxLen = j-i
}
}
return maxLen
}