[LeetCodeNote][java][HashSet|滑动窗口]3. 无重复字符的最长子串


3. 无重复字符的最长子串 - 力扣(LeetCode) (leetcode-cn.com)

题目描述:

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

  示例1:

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

  示例2:

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

  示例3:

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

  示例4:  

输入: s = ""
输出: 0

老规矩,先仍题解!

class Solution {
    public int lengthOfLongestSubstring(String s) {
        HashSet sites = new HashSet();
        int ans=0;
        int window=0;
        for(int i=0;i){
            if(i!=0){
                sites.remove(s.charAt(i-1));
            }
            while(windowsites.contains(s.charAt(window)))){
                sites.add(s.charAt(window));
                window++;
            }
            ans=Math.max(ans,window-i);
        }
        return ans;
    }
}

思路:

因为今天刷题小分队的任务一是最大子序和——一个动态规划的题

说实话第一反应竟然觉得题干挺像的?

但是字符串肯定不能用动态规划就是了

也想到了用map记录s.charAt(i)的出现,

后来看题解视频,他说“字符串是否出现过的模式试别:HashSet"

第一次用java的HashSet,但是好像HashSet是基于HashMap实现的,所以我的思路大概也不算错了?

再然后了解了滑块窗口的概念,挺好理解的

就是把当前的串框起来

起始用i记录,结束用window记录

第一次自己写的时候,while循环跳出后我竟然天真的认为,既然重复了,那把之前sites表清空重来就好了

真的太傻啦!

if的判断蛮经典的,一开始看没看懂 发现它是从上一次的框框开始从左到右依次删除然后判断while里面的判断

也就比如

a b c d c f g h

0 1 2 3 4 5 6 7

这个字符串的话,遍历到i=0,window=4时因为c出现过了,也就是sites.contains(c)为true

但是因为hashset无序,也没法直接找到在上一个框框里哪里出现的c

那么用框框的左边界i一个一个从左到右删除

把i=3,sites.remove(s.charAt(i-1))删掉之后,再次进入while循环,sites.contains(c)为false

此时左侧边界固定在i=3

继续移动右侧边界

太妙啦!!

评论区有人说不需要重复判断多次左边界 暂时没看懂 看懂回来更新