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

发布于:2024-05-18 ⋅ 阅读:(89) ⋅ 点赞:(0)

在这里插入图片描述

算法原理

这也是一道滑动窗口的题,可以使用暴力解法,也能使用滑动窗口。
写这类题主要就是注意那几步:
1)进窗口
2)判断
3)更新结果
4)出窗口
从一开始,我们就定义两个指针,同时指向0位置,让right指针向后走(进窗口),紧接着判断我们的hash表里是否有重复了(判断),如果重复了就出让left++(出窗口)直到hash表里重复的元素全出,再对个数进行更新(更新结果)。如果没有重复就直接将hash表里的对应元素++。这种算法能极大减少指针移动的次数,我们不需要像暴力解法那样让right 每次都要从头再来,而是只需要向后移动一遍就行了。

暴力解法(不超时):

其实写这个暴力解法,写的还不熟,总是忘了下一步该咋写,那就是不熟练,多写写应该就行了。

class Solution{
    public int lengthOfLongestSubstring(String ss){
        //暴力解法:
        int n =ss.length(),ret =0;
        //创建一个hash表来储存次数
        for(int i =0;i <n;i++){
        //之所以创建hash表的大小是128是因为,平常我们用到的所有字符的ascall码值几乎都在0^128内。可以去搜索一下验证验证
        int [] hash = new int [128];
            for(int j =i;j<n;j++){
                hash[(int)ss.charAt(j)]++;
                if(hash[(int)ss.charAt(j)]>1){//判断
                break;
            }
            ret = Math.max(j-i +1,ret);
            }
        }
    return ret;
    }
}
滑动窗口解法(更优)
class Solution{
    public int lengthOfLongestSubstring(String ss){
            char[] s = ss.toCharArray();
            int[] hash = new int[128]; // ⽤数组模拟哈希表
            int left = 0, right = 0, n = ss.length();
            int ret = 0;
            while(right < n){
                hash[s[right]]++; // 进⼊窗⼝
                while(hash[s[right]] > 1) // 判断
                hash[s[left++]]--; // 出窗⼝
                ret = Math.max(ret, right - left + 1); // 更新结果
                right++; // 让下⼀个字符进⼊窗⼝
        }
    return ret;
    }
}