3. 无重复字符的最长子串

431 阅读1分钟

思路: 滑动窗口

双指针,快指针在前面扫,不断把字符放到map中,遇到重复的停下,慢指针跳到重复元素第一次出现位置的下一个位置,继续操作。 关键点在于

  • i跳到重复数字的下一个后,要记得删除之前的map,否则会对之后的数字造成影响。

2. 优化版

IMG_5AA3D7EDAEA8-1.jpeg

class Solution {
    public int lengthOfLongestSubstring(String s) {
        Map<Character, Integer> map = new HashMap<>();
        int i = 0;
        int j = 0;
        int max = 0;
        while (j < s.length()) {
            //&&后的条件使得慢指针之前的字符被忽略,从而省去了remove的时间
            if (map.containsKey(s.charAt(j)) && map.get(s.charAt(j)) >= i) {
                i = map.get(s.charAt(j)) + 1; // 遇到重复字符,收左边界
                // j++; no
            } else {
                map.put(s.charAt(j), j);
                max = Math.max(max, j - i + 1);
                j++; //未遇到重复字符,扩展右边界
            }
        }
        return max;
    }
}

1. 未优化版本

class Solution {
    public int lengthOfLongestSubstring(String s) {
        //用来存放字符和对应的索引值
        Map<Character, Integer> map = new HashMap<>();
        int i = 0;//慢指针
        int j = 0;//快指针
        int max = 0;//最大长度
        while (j < s.length()) {
            //当快指针遇到重复的字符时,慢指针跳到重复值第一次出现的位置+1
            //然后再删掉慢指针位置之前的map,防止对后面造成影响
            if (map.containsKey(s.charAt(j))) {
                i = map.get(s.charAt(j)) + 1;
                for (int k = 0; k < i; k++) {
                    map.remove(s.charAt(k), k);//这样写会超时
                }
            } else {//当快指针没有遇到重复的字符,快指针++,计算max
                map.put(s.charAt(j), j);
                max = Math.max(max, j - i + 1);
                j++;
            }
            
        }
        return max;
    }
}