无重复字符的最长子串长度

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

示例 1:

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

示例 2:

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

示例 3:

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

示例 4:

输入: s = ""
输出: 0

提示:

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

Related Topics

哈希表

字符串

滑动窗口

👍 6759

👎 0

思路总结:

  1. 设置一个保留每个字符所在字符串中的位置的集合(可以通过HashMap或大小为128的数组来映射,数组通过ascll码表去映射)
  2. 滑动窗口,保证每个窗口里字母都是唯一的
  3. 如果出现重复字符,则将窗口的左界限设置为当前滑动窗口里重复字符的下一个位置,即下面的left = Math.max(left,map.get(s.charAt(i)) + 1)或 start = Math.max(start,last[index]+1); 并且HashMap或者数组中更新重复字符的位置(最大值)。
  4. 最后计算最长字符串的长度为 Math.max(max,i-left+1);
  5. 在需要多次循环时,可以先不考虑特殊情况,先把每一步都会做的代码写上,最后再去写特殊情况的代码。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UiyaYc2i-1642396730655)(C:\Users\zky\AppData\Roaming\Typora\typora-user-images\image-20220117130119167.png)]

//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
    public int lengthOfLongestSubstring(String s) {
        if(s.length()==0) return 0;
        int max = 0;//记录最大滑动窗口值
        int left = 0;///滑动窗口的左端
        Map<Character,Integer> map = new HashMap<>();
        for(int i = 0; i < s.length(); i++){
            if(map.containsKey(s.charAt(i))){
//                left = map.get(s.charAt(i))+1; abba 最后一个a会导致left变为0,所以需要求left和map中已经存在的值的最大值。
                left = Math.max(left,map.get(s.charAt(i)) + 1);//如果遇到重复字符,则将左端窗口值设置为重复字符的下一个值进行匹配。
            }
            map.put(s.charAt(i),i);
            max = Math.max(max,i-left+1);
        }
        return max;
    }
}
//leetcode submit region end(Prohibit modification and deletion)

blog.csdnimg.cn/9a237a3d7ee947f0b34e6ced4710b2b6.png)

优化后

//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
    public int lengthOfLongestSubstring(String s) {
 		int []last = new int[128];
        for(int i = 0; i<128; i++){
            last[i] = -1;
        }
        int res=0,start=0;

        for(int i = 0; i<s.length(); i++){

            int index = s.charAt(i);
            start = Math.max(start,last[index]+1);
            res = Math.max(res,i-start+1);
            last[index] = i;
            
        }

        return res;
    }
}
//leetcode submit region end(Prohibit modification and deletion)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IdJXq5eE-1642396730657)(C:\Users\zky\AppData\Roaming\Typora\typora-user-images\image-20220117125857946.png)]