lotus

贵有恒何必三更眠五更起 最无益只怕一日曝十日寒

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
  1846 随笔 :: 0 文章 :: 109 评论 :: 288万 阅读

1. 题目

 

题目

 https://leetcode.cn/problems/minimum-window-substring/

这道题目是要求给定两个字符串s和t,找出s中包含t中所有字符的最小子串,如果不存在这样的子串,就返回空字符串。

例如,输入s = "ADOBECODEBANC", t = "ABC",输出"BANC"。¹²

这道题目的难度是Hard,需要用到滑动窗口和哈希表的技巧

 

考查点

这道题考查的是滑动窗口的技巧,以及如何用哈希表来记录和判断字符的出现情况。

  • 滑动窗口是一种常用的处理字符串或数组的方法,可以有效地减少重复的计算和遍历。
  • 哈希表是一种常用的数据结构,可以快速地查找和更新键值对。
  • 2. 解法

 

解题思路

这个问题的关键是找到一个包含 t 中所有字符的最小子串,也就是说,这个子串中每个字符的出现次数要大于等于 t 中对应字符的出现次数。为了做到这一点,我们可以用一个哈希表来记录 t 中每个字符的出现次数,然后用两个指针 left 和 right 来维护一个滑动窗口,表示当前考虑的子串。初始时,left 和 right 都指向 s 的第一个字符。

我们从右边开始扩展窗口,每次移动 right 指针,如果 right 指向的字符在 t 中出现过,就把哈希表中对应的值减一。如果减一后的值等于零,说明我们已经找到了 t 中的一个字符,并且出现次数刚好满足要求。为了记录这种情况,我们用一个变量 count 来表示 t 中不同字符的个数,每次找到一个字符就把 count 减一。当 count 等于零时,说明我们找到了一个包含 t 中所有字符的子串。

接下来,我们要尝试缩小窗口,从左边开始移动 left 指针,如果 left 指向的字符在 t 中出现过,就把哈希表中对应的值加一。如果加一后的值大于零,说明我们失去了 t 中的一个字符,并且出现次数不再满足要求。为了记录这种情况,我们把 count 加一。当 count 大于零时,说明我们需要继续扩展窗口。

在这个过程中,我们每次找到一个有效的窗口时,就更新最小长度和起始位置。最后,我们返回最小长度对应的子串或者空字符串。

 

好的,我可以用以下的步骤来总结我的思路:

  1. 创建一个哈希表 map,记录 t 中每个字符的出现次数。
  2. 初始化两个指针 left 和 right,都指向 s 的第一个字符,表示当前的窗口。
  3. 初始化一个变量 count,表示 t 中不同字符的个数。
  4. 循环以下步骤,直到 right 到达 s 的末尾:
    • 如果 right 指向的字符在 map 中存在,就把 map 中对应的值减一。如果减一后的值等于零,就把 count 减一。
    • 移动 right 指针,扩展窗口。
    • 如果 count 等于零,说明当前的窗口包含了 t 中所有字符,进入以下步骤:
      • 如果当前的窗口长度小于之前记录的最小长度,就更新最小长度和起始位置。
      • 如果 left 指向的字符在 map 中存在,就把 map 中对应的值加一。如果加一后的值大于零,就把 count 加一。
      • 移动 left 指针,缩小窗口。
  5. 返回最小长度对应的子串或者空字符串。

 

具体实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
class Solution {
    public String minWindow(String s, String t) {
        // Use a map to store the frequency of each character in t
        Map<Character, Integer> map = new HashMap<>();
        for (char c : t.toCharArray()) {
            map.put(c, map.getOrDefault(c, 0) + 1);
        }
         
        // Use two pointers to maintain a sliding window
        int left = 0;
        int right = 0;
        int count = map.size(); // The number of distinct characters in t
        int minLen = Integer.MAX_VALUE; // The minimum length of the window
        int start = 0; // The start index of the window
         
        while (right < s.length()) {
            char c = s.charAt(right);
            // If c is in t, decrease its frequency by one
            if (map.containsKey(c)) {
                map.put(c, map.get(c) - 1);
                // If c's frequency becomes zero, decrease the count by one
                if (map.get(c) == 0) {
                    count--;
                }
            }
             
            // Move the right pointer forward
            right++;
             
            // When the count is zero, we have found a valid window
            while (count == 0) {
                // Update the minimum length and start index if needed
                if (right - left < minLen) {
                    minLen = right - left;
                    start = left;
                }
                 
                char d = s.charAt(left);
                // If d is in t, increase its frequency by one
                if (map.containsKey(d)) {
                    map.put(d, map.get(d) + 1);
                    // If d's frequency becomes positive, increase the count by one
                    if (map.get(d) > 0) {
                        count++;
                    }
                }
                 
                // Move the left pointer forward
                left++;
            }
        }
         
        // Return the substring or empty string
        return minLen == Integer.MAX_VALUE ? "" : s.substring(start, start + minLen);
    }
}

  

3. 总结

 

posted on   白露~  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
历史上的今天:
2021-04-28 深入JVM关闭与关闭钩子
2021-04-28 ShutdownHook - Java 优雅停机解决方案
2021-04-28 RocketMQ性能优化
2021-04-28 RocketMQ调优心得总结
2021-04-28 RocketMQ性能优化【实战笔记】
2021-04-28 RocketMQ在面试中那些常见问题及答案+汇总
2019-04-28 24种设计模式的通俗理解
点击右上角即可分享
微信分享提示