无重复字符的最长子串

问题描述:给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:
输入: "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

//思路一:暴力解法,但是超过时间限制
public int lengthOfLongestSubstring(String s) {
    int res = 0;

    for(int i=0;i<s.length();i++){
        for(int j=i+1;j<= s.length();j++){
            String tmp = s.substring(i,j);
            if(contains(tmp)){
                res = Math.max(res,tmp.length());
            }
        }
    }
    return res;
}

//判断字符串s是否包含重复元素
//返回true,说明包含重复元素
private boolean contains(String s){
    char[] buf = s.toCharArray();
    Set<Character> set = new HashSet<>();
    for(char c : buf){
        if(set.contains(c)){
            return false;
        }
        set.add(c);
    }
    return true;
}

//思路二:滑动窗口解法
//1、l=0,r=-1,[l,r]是滑动窗口,freq[256]数组用于判断该滑动窗口是否存在重复元素:
//2、当加入的元素不是重复元素时,r+1,扩展该窗口
//3、其他情况,缩小该窗口,l+1
public int lengthOfLongestSubstring(String s) {
    int l = 0, r = -1;
    int[] freq = new int[256];

    int n =s.length();
    //记录最长长度
    int res = 0;
    while(l<n){
        if(r+1 < n && freq[s.charAt(r+1)]==0){ //扩展窗口
            r++;
            freq[s.charAt(r)]++;
        }else{ //缩小窗口
            freq[s.charAt(l)]--;
            l++;
        }
        res = Math.max(res,r-l+1);
    }
    return res;
}

参考:

posted @ 2024-02-04 22:55  行行行行星  阅读(32)  评论(0)    收藏  举报