leetcode-3-无重复字符的最长子串

注意是子串
本题重要的是明白什么时候改变左边界

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 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;
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。