LeetCode解题笔记 双指针 第八题 [3. 无重复字符的最长子串]

296 阅读1分钟

题目

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

示例 1:

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

示例 2:

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

示例 3:

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

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/lo…

解题思路

  • 双指针+滑动窗口: 两个指针就是窗口的两个边框.
  • 就是通过缩放窗口,也就是移动左窗框的指针,将最大的子串框出来.

具体代码逻辑,请看注释.

代码

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int length = s.length();
        // 存储最长字符串
        int max = 0;
        // 用来装无重复字符,和其最大下标的
        Map<Character,Integer> map = new HashMap();
        char[] sc = s.toCharArray();
        // 记录窗口的开始位置,窗口从左往右移
        int start = 0;
        for(int i = 0 ; i < length ; i++){
            
            if(map.containsKey(sc[i])){
                // 如果存在,判断其是在窗口外边还是里面.
                // 如果在窗口外面,也就是开始,则不管(之所以移动就是因为有重复字符,往回移动不扯淡嘛))
                // 在里面,则将窗口移动到此位置
                start = Math.max(map.get(sc[i]),start);
            }
            // 每走一步,就要和最大值比一下,如果大,就更新.i就是窗口的右边框
            max = Math.max(i - start + 1,max);
            // key存的是: 字符,用来比较的,value存的是: 如果比较成功,用来和start,也就是左边窗口比较的下标
            map.put(sc[i],i+1);
        }
        return max;
    }
}