注意是子串
本题重要的是明白什么时候改变左边界
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
废话不多说,先上我写的trash
class Solution {
public int lengthOfLongestSubstring(String s) {
Set set = new HashSet();
for(int i=0;i<s.length();i++)
{
set.add(s.charAt(i));
}
if(set.size()==1) return 1;
int right=0;
int left=0;
int maxlength=0;
int[] freq = new int[200];
for(char c:s.toCharArray()){
freq[c]++;
}
while(right<s.length()){
char charRight = s.charAt(right);
if(freq[charRight]==1 && s.charAt(right)!=s.charAt(left)){
maxlength = maxlength>(right-left+1) ? maxlength:(right-left+1);
}
else if(freq[charRight]>1){
freq[charRight]--;
left++;
}
right++;
}
return maxlength;
}
}
非常凄惨,只能通过题目上给的三个用例,一提交就错了。
主要原因就在于我不知道如何处理滑动窗口的左边界。
根据题解的提示,如果在子串中左边界未滑动前包含了其他重复字符,那么就向末尾方向滑动,舍弃包含重复字符的子串。
上一下多方参考勉强AC的答案
class Solution {
public int lengthOfLongestSubstring(String s) {
if(s.length()==0) return 0;
HashMap<Character,Integer> map = new HashMap<>();
int left=0;
int right=0;
int maxlength=0;
while(right<s.length())
//right范围:「0,s.length()-1」
{
//如果已经包含了这个字符
if(map.containsKey(s.charAt(right)))
//那么left就重新限制左边界,舍弃重复字符中出现过的那个
left= Math.max(left,map.get(s.charAt(right))+1);
map.put(s.charAt(right),right);
right++;
//对于已知的子串,记录一下maxlength
maxlength=Math.max(maxlength,right-left);
}
return maxlength;
}
}