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

示例 1:

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

示例 2:

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

示例 3:

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

示例 4:

  1. 输入: s = ""
  2. 输出: 0

提示:

  • 0 <= s.length <= 5 * 10^4
  • s 由英文字母、数字、符号和空格组成

    解法一:滑窗

需要注意一个点: left < idx +1 为什么要这么写呢?如果不加会怎样呢?
例如 "abba"

  • right = 2 时, 这时候 window 里存在这个值,然后把 left 赋值成 上一次出现位置的下一个节点, 也就是 2。当前长度是 right - left + 1 即 1
  • right = 3 时,这时候 window 里存在这个值,然后把 left 赋值成 上一次出现位置的下一个节点,也就是 1。当前长度是 right - left + 1 即 3, 显然这时候是不对的。
    1. func lengthOfLongestSubstring(s string) int {
    2. left, right := 0, 0
    3. // key 字符 val 最后一次出现的位置
    4. window := make(map[byte]int)
    5. n := len(s)
    6. res := 0
    7. for right < n {
    8. cur := s[right]
    9. // "abba"
    10. if idx, ok := window[cur]; ok && left < idx+1 {
    11. left = idx + 1
    12. }
    13. window[cur] = right
    14. if res < right-left+1 {
    15. res = right - left + 1
    16. }
    17. right++
    18. }
    19. return res
    20. }