zoukankan      html  css  js  c++  java
  • leetcode之滑动窗口算法小结

    leetcode刷题——总结字符串滑动窗口思想解法

    做了一些字符串题目后,查看题解的时候看到了滑动窗口思想,之前都没有去了解过,看一些文章也比较模糊,想自己总结弄懂,然后能够讲接地气给你们看。

    是什么

    【滑动窗口算法】(sliding window algorithm)--想必大家都有在平常生活中遇到过滑动窗口的场景,这个算法浅白来讲就是这样的感觉,滑动窗口(满足了连续的位置),改变长度或者位置,去获得不同要求的结果,很明显的是这个窗口滑动距离满足不超过这个窗户整体长度,所以在处理一些字符/数组的子部分的问题时候,可能就派上用场了。

    简单的数组滑动实例:

    leetcode3-求无重复字符的最长子串长度

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

    image-20200523132319424

    滑动窗口问题的解决一般都得设置好双指针

    leetcode76-最小覆盖子串

    image-20200523101638056

    答案解析如下

    image-20200523110555077

    模板

    在leetcode上有一位大佬总结出来了模板,可以参考下

    大致逻辑如下

    int left = 0, right = 0;
    
    while (right < s.size()) {`
        // 增大窗口
        window.add(s[right]);
        right++;
        
        while (window needs shrink) {
            // 缩小窗口
            window.remove(s[left]);
            left++;
        }
    }
    //对应上面的例题,中间的while条件需要自己去修改,原理是一样的,遇到不符合的条件,就调整窗口大小
    
    
      public List<Integer> findAnagrams(String s, String p) {
            List<Integer> list = new ArrayList<>();
            int left = 0 , right = 0;
            char[] needs = new char[128];             //相当于hashMap,用于记录每个字符的个数
            char[] windows = new char[128];
            for (int i = 0; i < p.length(); i++) {
                needs[p.charAt(i)]++;
            }
            //统计符合要求字符个数
            int count =0;
            while(right < s.length()){
    
                char ch = s.charAt(right);
                windows[ch]++;
                if (needs[ch] > 0 && needs[ch] >= windows[ch]){
                    count++;
                }
                //长度满足条件
                while( count == p.length()){
                    //加入符合要求的结果
                    if (right + 1 - left == p.length()){
                        list.add(left);
                    }
                    //经过一轮的条件满足,要向下继续寻找,不符合下面要求,则滑动窗口,往右走
                    char ch1 = s.charAt(left);
                    //这一步是有点难理解的,一开始我是结合例子,步步过才掌握了。很巧妙
                    if (needs[ch1] > 0){
                        //这里是通过剔除已经满足的窗边位置,这样才可以往下走,重新往右搜索
                        windows[ch1]--;
                        if ( windows[ch1] < needs[ch1]){
                            count--;
                        }
                    }
                    left++;
                }
                right++;
            }
            return list;
        }
    

    作用

    • 滑动窗口算法可以解决字符串或者数组的一些子部分问题,比如一些要求连续的子部分
    • 同时可以提高效率,减低时间复杂度,将嵌套问题优化。
    • 在有些字符串情况下,比kmp算法还要高效
  • 相关阅读:
    SmartTimer——一种基于STM32的轻量级时钟调度器
    Python2/3中的urllib库
    Python 解析构建数据大杂烩 -- csv、xml、json、excel
    Python2/3 中执行外部命令(Linux)和程序(exe) -- 子进程模块 subprocess
    Python 中的命令行参数处理 -- argparse、optparse、getopt
    Linux 定时循环执行 python 脚本
    Python2/3的中、英文字符编码与解码输出: UnicodeDecodeError: 'ascii' codec can't decode/encode
    在windows下使用Qt5开发GTK3图形界面应用程序
    qt编译的基于xlib cairo的桌面程序
    debian安装dwm窗口管理器
  • 原文地址:https://www.cnblogs.com/yhycoder/p/12949549.html
Copyright © 2011-2022 走看看