Leetcode76覆盖最小子串

覆盖最小子串

  • 代码来自b站左程云
java 复制代码
class Solution {
    public String minWindow(String str, String tar) {
        char[] s = str.toCharArray();
        char[] t = tar.toCharArray();
        int[] cnt = new int[256];
        for (char cha : t) { 
            cnt[cha]--;
        }
        int len = Integer.MAX_VALUE;
        int debt = t.length;
        int start = 0;
        for (int r = 0, l = 0; r < s.length; r ++) { 
            if (cnt[s[r]]++ < 0) { 
                debt--;
            }
            if (debt == 0) { 
                while (cnt[s[l]] > 0) { 
                    cnt[s[l++]]--;
                }
                if (r - l + 1 < len) { 
                    len = r - l + 1;
                    start = l;
                }
            }

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

画图理解题意

  • 我们先梳理一下思路:
  1. 我们要确定这个窗口有没有包含target字符串中的每一个字符,难道我们要遍历比较吗?显然不行,那么怎么样让它遍历一次就知道是否包含呢?
  2. 我们利用之前前缀和中哈希表的思路,我们把target字符串的每个字符出现的次数作为每个字符欠债的个数存到数组中,把它弄成一个前债表。
  • 我们看第一个样例:

初始的欠债表为:

说明此时我们要找到一个满足ABC每个字符各一个的组合。


当我们不断扩展右边界,会发现第一次满足条件的窗口是这样的:

可是题目要我们求最短啊,我们尝试收缩左边界,收缩的时候要注意,如果收缩会导致欠债那么就不能收缩,只能记住答案,拿去与之前比大小看是否能更新。

然后继续扩展右边界:

此时我们发现,不仅不欠债还有了结余可以尝试收缩。

继续这样推下去,就是不断进行这个判断过程:

理解代码:

java 复制代码
    if (cnt[s[r]]++ < 0) { 
         debt--;
    }

这里是把每一个字符扔到欠债表里面进行结算,如果是target里面的,说明他刚开始是负的,所以我们用是否小于0来判断是否可以对欠债总数debt来进行削减,到0的时候就说明我们要开始尝试收缩窗口了。

java 复制代码
          if (debt == 0) { 
                while (cnt[s[l]] > 0) { 
                    cnt[s[l++]]--;
                }
                if (r - l + 1 < len) { 
                    len = r - l + 1;
                    start = l;
                }
            }

要判断左边是否可以削减,就要看它的削减会不会导致债务的增加,也就是会不会导致现在的窗口不能完全包含target,所以进行此判断。

然后我们就要看这个窗口长度是不是目前最短的,是的话就更新它,同时记住此时左边界,为什么?因为我们要返回的是一个字符串,截取一个子串需要它的长度和起始位置。

相关推荐
罗西的思考20 小时前
[Agent Memory / 强化学习] MemPO源码学习笔记 ---(1)--- 总体
人工智能·算法·机器学习
lvwangshu21 小时前
图论:LCA、树的直径、树的重心、二分图与 Tarjan 缩点
算法·图论
爱吃苹果的日记本21 小时前
数据结构第一课
c语言·数据结构·数据库·学习·c#
孫治AllenSun1 天前
【LangChain4J-09】开发学习知识点
spring boot·后端·学习
302wanger1 天前
干与湿:AI 拿走脑力之后,人剩下什么
算法
边境悍匪1 天前
蜗牛学苑 Java 智能体学习 Day38|Spring AI Alibaba2 思维导图复盘
java·学习·spring
计算机编程-吉哥1 天前
脑肿瘤MRI智能识别系统:基于深度学习的像素级脑肿瘤语义分割平台【计算机毕业设计选题推荐】
人工智能·python·深度学习·算法·毕业设计·课程设计·大数据毕业设计选题推荐
自小吃多1 天前
高云FPGA ModelSim中的仿真
笔记·嵌入式硬件·fpga开发
摘星星的屋顶1 天前
2026年8月31日~2026年9月13日周报
人工智能·学习
用户204937554951 天前
端侧语音部署踩坑:模型能跑不等于终端真的能用
后端·算法