3. 无重复的最长子串

126 阅读1分钟

leetcode无重复的最长子串

方法:滑动窗口

p1: hashset

HashSet hs = new HashSet<>();

 //hashset保存
    public int lengthOfLongestSubstring1(String s) {
        HashSet<Character> hs = new HashSet<>();
        int len = s.length();
        int maxlen = 0;
        int i = 0, j = 0;
        while(i < len && j < len){
            if(!hs.contains(s.charAt(j))){
                hs.add(s.charAt(j));
                j++;
                maxlen = Math.max(maxlen, j-i); //j已经加1所以长度不需要+1
            }
            else{
                //重点,一直移除,直到没有重复字符
                hs.remove(s.charAt(i++)); //移除重复字符之前的所有字符,保证滑动窗口i-j中不重复
            }

        }
        return maxlen;
      
    }

p2: hashmap

HashMap<Character, Integer> hm = new HashMap<>();

 //hashmap保存char和char的下标,保存滑动窗口[i,j]
    public int lengthOfLongestSubstring(String s) {
        HashMap<Character, Integer> hm = new HashMap<>();
        int len = s.length();
        int maxlen = 0;
        
        // for (int j = 0, i = 0; j < n; j++) {
        //     if (map.containsKey(s.charAt(j))) {
        //         i = Math.max(map.get(s.charAt(j)), i);
        //     }
        //     ans = Math.max(ans, j - i + 1);
        //     map.put(s.charAt(j), j + 1);
        // }
        int i = 0, j = 0;
        while(i < len && j < len){
            //无论重不重复j都要向后,map都要保存j的值
            if(!hm.containsKey(s.charAt(j))){
                hm.put(s.charAt(j), j);
                j++;
                maxlen = Math.max(maxlen, j-i);
            }
            else{
                //i取值重点
                //i取i和当前重复值下标的下一位两者的最大值
                //这样保证j再向后的之后如果与i之前的元素重复可以忽略(i不变)
                //hm不必去考虑滑动窗口前的值,不会像hashset一样需要一直删除滑动窗口前面的值
                i = Math.max(hm.get(s.charAt(j)) + 1, i); 

                hm.put(s.charAt(j), j);
                j++;
                maxlen = Math.max(maxlen, j-i);
            }
        }
        return maxlen;
    }