03.滑动窗口,启动!

滑动窗口

滑动窗口是一种基于双指针思想的算法。两个指针指向的元素之间会形成一个窗口,从前往后遍历元素进行一定的运算。

无重复字符的最长字串

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

  • 分析:
    判断一个字符串是否存在重复字符—>新加入的字符在一个不包含重复字符的串中是否出现过。
  • 方法
    1.维护一个窗口,保证窗口内为不含有重复字符的子串,记录窗口的左右边界,(右边界即为当前遍历的字符下标)。
    2.维护一个hash表,以字符为键,以当前该字符出现的最左位置为值。
    3.窗口左边界初值为0,逐步滑动右边界,若出现了一个当前遍历过程中出现过的字符(hash表中存在),则判断该字符上一次出现的位置是否大于左边界,若大于,则更新左边界,否则说明其并不在窗口内。
    4.每一次滑动后都动态计算当前窗口长度,并维护出现过的最大窗口长度。
    5.返回结果。
  • 也可以用整数数组来替代hash表,注意,字符串中可能存在空格、数字和字母
class Solution {
    public int lengthOfLongestSubstring(String s) {
        if(s==null||s.length()==0)
            return 0;
        int max_l = 1;
        int cur_l = 1;
        int lastindex = 0;
        int[] index = new int[128]; //默认初始化值0
        for (int i = 0; i < 128; i++) {
            index[i] = -1;
        }
        index[s.charAt(0)-' ']=0;
        for (int i = 1; i < s.length(); i++) {
            final char c = s.charAt(i);
            if(index[c-' ']!=-1){
                lastindex = Math.max(index[c-' ']+1,lastindex);
            }
            index[c-' ']=i;
            cur_l = i-lastindex+1;
            max_l=Math.max(cur_l,max_l);
        }
        return max_l;
    }
}

找到字符串中所有字母的异位词

给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。

  • 分析
    1.两个词组为异位词—>两个词的原料相同,可用一个整数数组/自定义类来表示一个字符串。
    2.使用滑动窗口,大小与p相同,每次向右滑动,仅需去掉左边界字符,加上新字符即可,减少重复计算。
class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        List<Integer> res = new ArrayList<>();
        int l = p.length();
        if(l>s.length()) return res;
        int[] target = count(p, 0, l);
        int[] count = count(s, 0, l - 1);
        for (int i = 0; i < s.length()-l+1; i++) {
            count[s.charAt(i+l-1)-'a']++;
            if(Arrays.equals(count,target)){
                res.add(i);
            }
            count[s.charAt(i)-'a']--;
        }
        return res;
    }
    private int[] count(String s,int start,int end){
        int[] res = new int[26];
        for (int i = start; i < end; i++) {
            res[s.charAt(i)-'a']++;
        }
        return res;
    }
}
  • 延申
    类似于计算长度为k的连续子数组的最大总和。

窗口内的最大值

给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。返回滑动窗口中的最大值 。

  • 分析
    需要结合单调递减的双端队列
    https://zhuanlan.zhihu.com/p/694074757

总结

滑动窗口方法,主要通过维护窗口内的数据,从而减少重复计算。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值