3.无重复字符的最长子串

2020-11-27  本文已影响0人  土豆泥加冰谢谢

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 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 由英文字母、数字、符号和空格组成

    public static int lengthOfLongestSubstring(String s) {
        //定义窗口性质:[left,right]前闭后闭范围内无重复字符
        int ret=0;
        //窗口左指针
        int left=0;
        //窗口右指针
        int right=0;
        Map<Character,Integer> windowData=new HashMap<>();
        while(right<s.length()){
            Character item=s.charAt(right);
            if (windowData.containsKey(item)){
                //遇到重复子串
                //先记录下最大的连续长度
                ret=Math.max(right-left,ret);
                //接着对窗口数据进行维护,保证连续不重复,即移除窗口中重复字符和之前的字符,并且将left后移
                int tempIndex=windowData.get(item);
                for (int i=left;i<=tempIndex;i++){
                    windowData.remove(s.charAt(i));
                }
                left=tempIndex+1;
            }else if(right==s.length()-1){
                //如果走到末尾了,不要漏掉计算一次长度结果,因为可能在某次冲突后或者从未冲突,一直到结尾都是连续不重复的字符串
                ret=Math.max(s.length()-left,ret);
            }
            //窗口继续右移判断下一位,并将当前数据纳入窗口
            windowData.put(item,right);
            right++;
        }
        return  ret;
    }

主要在于维护窗口性质,以及不要漏掉边界问题,例如整个字符串均连续不重复例如abcdefg,或者字符串结尾前一段字符为连续非重复例如:adbdeda.....abcdefg
//采用map来维护窗口数据,因为记录了字符下标,所以我们可以直接遍历移除到不重复字符为止。
在出现变种题目的情况下,例如要获取所有的无重复子串,只需要在该逻辑下增加一个数据结构来存储所有结果即可

上一篇 下一篇

猜你喜欢

热点阅读