leetcode双指针 无重复字符的最长字串 java

题目描述
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。

方法一:
新建一个hashset,初始化两个指针i,j,i表示滑动窗口的起始位置,j表示滑动窗口的终止位置,num表示返回的字符串长度。
如果set中不含有第j个字母,则将第j个字母加到set中,j+1, num取的是num和j-i中的较大值
如果set中包含第j个字母,则将滑动窗口的起始位置+1,然后继续判断 【注意:这里j并没有做加一操作,所以下次循环还会继续和上次循环一样的判断,直到窗口中无重复元素】
比如:
a b b c d
第一次 把a加入set,i = 0,j =1
第二次 把b加入set,i = 0 j = 2
第三次 s.charAt(2) = b set中包含b,所以 i +1 = 1
第四次 s.charAt(2) = b set中包含b,所以 i + 1 = 2
第五次 s.charAt(2) = b i = 2 j+1 = 3

相当于一个滑动窗口先变大后变小再变大的过程

代码:

class Solution {
    
    
    public int lengthOfLongestSubstring(String s) {
    
    
        int num = 0;
        Set<Character> set = new HashSet<>();//创建滑动窗口
        int j=0,i = 0;
        while(i<s.length()&&j<s.length()){
    
    
            if(!set.contains(s.charAt(j))){
    
    
                set.add(s.charAt(j));
                j++;
                num = Math.max(num,j-i);
            }else{
    
    
                set.remove(s.charAt(i));
                i++;
            }
        }
        return num;
    }
}

方法二:
如果出现重复元素,则初始位置指针指向出现过位置的下一个位置
因为需要更新初始位置的下标而不是像上面那样加一操作,所以需要用到HashMap,map.get(s.charAt(i))
比如:
a b b c d
第一次 i=0 把(a,0)加入map
第二次 i=1 把(b,1)加入map
第三次 i=2 map中包含b,则left = max(0,1+1)=2 ,然后把(b,2)加入map【注意:map的key不会重复,所以会覆盖(b,1)】,当前map中的元素为(a,0)和(b,2)
第四次 i = 3 把(c,3)加入map
第五次 i = 4 把(d,4)加入map

class Solution {
    
    
    public int lengthOfLongestSubstring(String s) {
    
    
        int num = 0;
        Map<Character,Integer> map = new HashMap<>();    
        int left = 0;
        for(int i = 0;i<s.length();i++){
    
    
            if(map.containsKey(s.charAt(i))){
    
    
                left = Math.max(left,map.get(s.charAt(i))+1);
            }
            map.put(s.charAt(i),i);
            num = Math.max(num,i-left+1);
        }
         
        return num;

    }
}

猜你喜欢

转载自blog.csdn.net/stonney/article/details/111029976
今日推荐