[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) { HashSetsites = new HashSet (); int ans=0; int window=0; for(int i=0;i ){ if(i!=0){ sites.remove(s.charAt(i-1)); } while(window sites.contains(s.charAt(window)))){ sites.add(s.charAt(window)); window++; } ans=Math.max(ans,window-i); } return ans; } }
思路:
因为今天刷题小分队的任务一是最大子序和——一个动态规划的题
说实话第一反应竟然觉得题干挺像的?
但是字符串肯定不能用动态规划就是了
也想到了用map
后来看题解视频,他说“字符串是否出现过的模式试别: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
继续移动右侧边界
太妙啦!!
评论区有人说不需要重复判断多次左边界 暂时没看懂 看懂回来更新