题解 1:
维持一个滑动窗口来做比较,初始时使左右边界指针从 0 出发,并维护一个 【字符】 => 【位置】 的 map。
首先右指针向前走,判断当前字符是否在 map 中,存在则判断 map 值是否在窗口内,存在左指针前移,否则右指针前移并更新 map 中的值。字符不存在则存在 map 中。 耗时 0 ms
package main
import (
"fmt"
"strings"
)
func main() {
s := "abcabcbb"
fmt.Println(getLongStr(s))
}
func getLongStr(s string) int {
sArr := strings.Split(s, "")
// 存储字符对应的下标值 多次出现的字符保持最新的下标
sMap := make(map[string]int)
// 结果
res := 0
sLen := len(s)
// 左边界
l := 0
// 右边界
r := 0
for r < sLen {
i, ok := sMap[sArr[r]]
if ok {
// 下标在窗口(即边界)范围内
if i <= r && i >= l {
// 左边界 ++
l++
} else if r < sLen {
// 防止越界
sMap[sArr[r]] = r
r++
} else {
break
}
} else {
// 右边界 ++
sMap[sArr[r]] = r
r++
}
if (r - l) > res {
res = r - l
}
//fmt.Printf("i=%v res=%v ok=%v l=%v r=%v\n", i, res, ok, l, r)
}
return res
}
题解 2:
维持一个 map ,保持最新字符出现的位置,耗时 4 ms
package main
import "fmt"
func main() {
s := "abcabcbb"
fmt.Println(lengthOfLongestSubstring(s))
}
func lengthOfLongestSubstring(s string) int {
left := 0
res := 0
sMap := make(map[string]int)
for i := 0; i < len(s); i++ {
temp := s[i : i+1]
v, ok := sMap[temp]
if ok && v > left {
left = v
}
if (i - left + 1) > res {
res = i - left + 1
}
sMap[temp] = i + 1
}
return res
}