2024-04-18---中等题---无重复字符的最长子串(滑动窗口)

无重复字符的最长子串(滑动窗口)

题目:

思路:

一 暴力法:

  1. 特殊情况,长度为0或者1

  2. 声明每次位置的最大长度,和最大的最大值(返回值)

  3. 双层循环,有点暴力

二 滑动窗口:

​ 基本概念:维持一个窗口(可以理解为队列),当新进来的元素与前面的重复,则把重复的元素及之前的元素全部忽略(可以理解为移出队列)。也就形成了窗口在字符串上平滑移动。

​ 本题思路:

  1. 特殊情况,长度为0返回0

  2. 新建一个Map<Character,Integer> map,用来查重和移动窗口

  3. 初始化result,left为0.result记录返回的最大长度,left记录窗口的起始位置。

  4. 一次遍历:当有重复,更新left

    ​ 否则put当前数据,并返回更大的值给result.

  5. 遍历结束,返回结果

先看思路,不看代码去实现,实现后再看。

代码:

暴力法

java 复制代码
public int lengthOfLongestSubstring(String s) {
        if(s.length()==0) return 0;
        if(s.length()==1) return 1;
        int maxLength = 0;
        int result = 1;
        for (int i = 0; i < s.length(); i++) {
            HashSet set = new HashSet();
            set.add(s.charAt(i));
            maxLength=1;
            for (int j = i+1; j <s.length() ; j++) {
                if(!set.contains(s.charAt(j))){
                    set.add(s.charAt(j));
                    maxLength++;
                    result = Math.max(maxLength,result);
                }else {
                    break;
                }
            }
        }
        return result;
    }

滑动窗口:

java 复制代码
public int lengthOfLongestSubstring1(String s) {
    if(s.length()==0) return 0;
    Map<Character,Integer> map = new HashMap<Character,Integer>();
    int result=0;
    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);
        result = Math.max(result,i-left+1);
    }
    return result;
}