LeetCode——滑动窗口

滑动窗口

包含特定元素的子串(要匹配到的目标),或最长[这个好像没啥意思]、或最短、或等长

思考:(暂时感受)

1)什么时候扩充窗口——串没走完就得扩呀;

2)窗口扩充后要更新哪些东西——窗口包括的内容,毕竟新来人了,东西多了;

3)什么时候缩小窗口——得看目标条件是啥了,最短的情况吧只要目标条件够了就得收缩,等长的情况吧等长就得缩噻;

4)窗口缩小后要更新哪些东西——窗口包括的内容;

5)什么时候更新结果——收缩的时候,还是一轮结束的时候。

1. 最小覆盖子串 76 简单

class Solution {
    public String minWindow(String s, String t) {
        // 两个Map记录目标字符以及窗口包含的字符
        Map<Character, Integer> need = new HashMap<>();
        Map<Character, Integer> window = new HashMap<>();

        // 填充目标字符的Map
        for (char c: t.toCharArray()) {
            need.put(c, need.getOrDefault(c, 0) + 1);
        }

        // 设置左右指针,区间范围是左闭右开,所以刚开始区间内没有元素
        int left = 0;
        int right = 0;
        int valid = 0;  // 窗口中满足需要的字符个数
        // 记录最小覆盖子串的起始索引和长度
        int start = 0;
        int len = Integer.MAX_VALUE;

        // 扩大窗口至覆盖子串
        while (right < s.length()) {
            char c = s.charAt(right);
            // 扩大窗口
            right ++;
            // 对窗口内的数据进行更新
            if (need.containsKey(c)) {
                window.put(c, window.getOrDefault(c, 0) + 1);
                if (window.get(c).equals(need.get(c))) {
                    // 窗口内某个字符满足个数要求了
                    valid ++;
                }
            }

            // 缩小窗口仍覆盖子串
            while (valid == need.size()) {
                // 更新最小覆盖子串
                if (right - left < len) {
                    start = left;
                    len = right - left;
                }
                // 缩小窗口
                char d = s.charAt(left);
                left ++;
                // 对窗口内的数据进行更新
                if (need.containsKey(d)) {
                    if (window.get(d).equals(need.get(d))) {
                        valid --;
                    }
                    window.put(d, window.get(d) - 1);
                }
            }

        }
        return len == Integer.MAX_VALUE ? "" : s.substring(start, start + len);

    }
}

2. 字符串的排列 567 中等

class Solution {
    public boolean checkInclusion(String s1, String s2) {
        // 思路:缩到最小覆盖,长度如果与s1相等,说明s1的排列之一是s2的子串
        // Map记录数量
        Map<Character, Integer> need = new HashMap<>();
        Map<Character, Integer> window = new HashMap<>();
        // 填充need
        for (char c : s1.toCharArray()) {
            need.put(c, need.getOrDefault(c, 0) + 1);
        }
        // 滑动窗口
        int left = 0;
        int right = 0;
        // int start = 0;
        // int len = Integer.MAX_VALUE;
        int valid = 0;
        while (right < s2.length()) {
            char c = s2.charAt(right);
            // 扩大窗口
            right ++;
            if (need.containsKey(c)) {
                window.put(c, window.getOrDefault(c, 0) + 1);
                if (window.get(c).equals(need.get(c))) {
                    valid ++;
                }
            } 
            while (right - left >= s1.length()) {
            // while (valid == need.size()) {
                // if (right - left < len) {
                //     start = left;
                //     len = right - left;
                // }
                // 判断是否找到了合适的子串
                if (valid == need.size()) {
                    return true;
                }
                char d = s2.charAt(left);
                left ++;
                if (need.containsKey(d)) {
                    if (window.get(d).equals(need.get(d))) {
                        valid --;
                    }
                    window.put(d, window.get(d) - 1);
                }
            } 
            // if (len == s1.length()) {
            //     return true;
            // }
        }
        return false;
    }
}

3. 找到字符串中所有字母异位词 438 中等

class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        // 存放结果
        List<Integer> result = new ArrayList<>();
        // 存放窗口元素
        Map<Character, Integer> need = new HashMap<>();
        Map<Character, Integer> window = new HashMap<>();
        for (char c : p.toCharArray()) {
            need.put(c, need.getOrDefault(c, 0) + 1);
        }
        // 滑动窗口的左右指针
        int left = 0;
        int right = 0;
        int valid = 0;
        while (right < s.length()) {
            char c = s.charAt(right);
            // 扩大窗口
            right ++;
            if (need.containsKey(c)) {
                window.put(c, window.getOrDefault(c, 0) + 1);
                if (need.get(c).equals(window.get(c))) {
                    valid ++;
                }
            }
            while (right - left >= p.length()) {
                if (valid == need.size()) {
                    result.add(left);
                    // // window和valid要清空
                    // window.clear();
                    // valid = 0;
                }
                char d = s.charAt(left);
                left ++;
                if (need.containsKey(d)) {
                    if (window.get(d).equals(need.get(d))) {
                        valid --;
                    }
                    window.put(d, window.get(d) - 1);
                }
            }
        }
        return result;
    }
}

4. 无重复字符的最长子串 3 中等

class Solution {
    public int lengthOfLongestSubstring(String s) {
        // 结果
        int result = 0;
        // 滑动窗口:重要的是如果map中键的值超过2,那就说明需要缩小窗口了
        Map<Character, Integer> window = new HashMap<>();
        int left = 0;
        int right = 0;
        while (right < s.length()) {
            char c = s.charAt(right);
            right ++;
            window.put(c, window.getOrDefault(c, 0) + 1);
            while (window.get(c) > 1) {
                char d = s.charAt(left);
                left ++;
                window.put(d, window.get(d) - 1);
            }
            // 更新答案
            result = Math.max(result, right - left);
        }
        return result;
    }
}

【未完待续……】

相关推荐

  1. LeetCode——滑动窗口

    2024-05-03 11:12:04       16 阅读
  2. leetcode滑动窗口题目总结

    2024-05-03 11:12:04       13 阅读
  3. leetcode滑动窗口问题总结 Python

    2024-05-03 11:12:04       28 阅读
  4. Leetcode】239. 滑动窗口最大值

    2024-05-03 11:12:04       39 阅读
  5. LeetCode】239. 滑动窗口最大值

    2024-05-03 11:12:04       28 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-05-03 11:12:04       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-05-03 11:12:04       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-05-03 11:12:04       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-05-03 11:12:04       20 阅读

热门阅读

  1. centos 中使用 kubekey 安装 k8s v1.22.12 支持 GPU 调用

    2024-05-03 11:12:04       12 阅读
  2. Django框架之模型层

    2024-05-03 11:12:04       11 阅读
  3. CentOS:增加网桥可以通过brctl命令

    2024-05-03 11:12:04       13 阅读
  4. RISC-V异常处理相关内容

    2024-05-03 11:12:04       11 阅读
  5. 云计算技术概述_2.云计算的服务方式

    2024-05-03 11:12:04       12 阅读
  6. 3DMax中场景太大如何优化?

    2024-05-03 11:12:04       9 阅读
  7. 【CSS】基础

    2024-05-03 11:12:04       10 阅读
  8. rust可变全局静态数组用法

    2024-05-03 11:12:04       12 阅读
  9. C# Solidworks二次开发:枚举应用实战(第十三讲)

    2024-05-03 11:12:04       10 阅读
  10. 游戏名台词大赏

    2024-05-03 11:12:04       11 阅读
  11. springboot-WebSocket

    2024-05-03 11:12:04       14 阅读
  12. 从零开始精通RTSP之传输H264视频流

    2024-05-03 11:12:04       11 阅读
  13. 04.25_111期_C++_map&set

    2024-05-03 11:12:04       13 阅读
  14. 03.磁盘管理与维护命令

    2024-05-03 11:12:04       12 阅读