当前位置: 首页 > article >正文

leetcode 76. 最小覆盖子串

题目如下
在这里插入图片描述

数据范围
在这里插入图片描述

首先本题可以利用不定长的滑动窗口思想不断枚举右端同时检查窗口是否符合题意。
但是这样做每次新枚举一个窗口都要检查造成了很多重复计算。
我们发现其实每次变化要么是少一个字符要么是多一个字符而中间的根本没变。
所以,我们令字符串t出现的字符种类为m,
在枚举右端点的过程中每当窗口内的某个字符出现频率增加到与字符串t一样时count++。
在m == count时我们会发现此时答案可能出现在窗口内,
所以我们不断移动左端点同时减少对应的字符的频数当这个频数小于t中的频数时显然我们不能移动左端点了。
在这个过程中不断得到最小长度以及子串起始地址然后返回即可。

未优化通过代码

class Solution {
public:
    bool check() {
        for (auto& p : mapt) {
            if (maps[p.first] < p.second)
                return false;
        }
        return true;
    }
    unordered_map<char, int> mapt, maps;
    string minWindow(string s, string t) {
        int n = s.size();
        int m = t.size();
        if (m > n)
            return "";

        for (char c : t)
            mapt[c]++;

        int l = 0, r = 0;
        int ans = INT_MAX;
        int st = 0;
        while (r <= n) {
            if (mapt.count(s[r])) {
                maps[s[r]]++;
            }
            r++;
            
            while (l <= r && check()) {
                if (r - l < ans) {
                    ans = r - l;
                    st = l;
                }

                if (mapt.count(s[l])) {
                    maps[s[l]]--;
                }
                l++;
                
            }
        }

        return ans == INT_MAX ? "" : s.substr(st, ans);
    }
};

在这里插入图片描述

优化后的通过代码

class Solution {
public:
    bool check() {
        for (auto& p : mapt) {
            if (maps[p.first] < p.second)
                return false;
        }
        return true;
    }
    unordered_map<char, int> mapt, maps;
    string minWindow(string s, string t) {
        int n = s.size();
        int m = t.size();

        if (m > n)
            return "";
        int count = 0;
        for (char c : t)
            mapt[c]++;
        m = mapt.size();
        int l = 0, r = 0;
        int ans = INT_MAX;
        int st = 0;
        while (r <= n) {
            if (mapt.count(s[r])) {
                maps[s[r]]++;
               // cout << maps[s[r]] << endl;
                if (maps[s[r]] == mapt[s[r]]) {
                    count++;
                }
                
                while (l <= r && count == m) {
                    //       cout << r << endl;
                    if (r - l + 1 < ans) {
                        ans = r - l + 1;
                        st = l;
                    }

                    if (mapt.count(s[l])) {
                        maps[s[l]]--;
                        if (maps[s[l]] < mapt[s[l]]) {
                            l++;
                            count--;
                            break;
                        }
                    }
                    l++;
                }
            }
            r++;
        }
        //  cout << ans;
        return ans == INT_MAX ? "" : s.substr(st, ans);
    }
};

在这里插入图片描述


http://www.kler.cn/a/568685.html

相关文章:

  • 基于专利合作地址匹配的数据构建区域协同矩阵
  • 功能丰富的自动化任务软件zTasker_2.1.0_绿色版_屏蔽强制更新闪退
  • Dify - 自部署的应用构建开源解决方案
  • 数据分享:空气质量数据-济南
  • 2025 GDC开发者先锋大会“人形机器人的开源之路”分论坛 | 圆桌会议:《开放协作:开源生态如何解锁人形机器人与具身智能的未来》(上篇)
  • iOS 18.4 深度更新解析:美食内容革命与跨设备生态重构(2025年4月)
  • Trae智能协作AI编程工具IDE:如何在MacBook Pro下载、安装和配置使用Trae?
  • Raspberry Pi边缘计算网关设计与LoRa通信实现
  • 高频 SQL 50 题(基础版)_626. 换座位
  • 嵌入式学习(29)-ASM330LHH驱动程序
  • 使用python解决硬币找零问题
  • MySQL远程连接Docker中的MySQL(2003,10061)等问题
  • MYISAM存储引擎介绍,特性(和innodb对比),优势,物理文件,表存储格式(静态表,动态表,null记录,压缩表)
  • 动态规划刷题
  • 计算机网络---SYN Blood(洪泛攻击)
  • 【计算机网络基础】-------计算机网络概念
  • ​Java 开发中的String判断空及在多种转换String字符串场景下的判断空
  • Rust学习总结之-枚举
  • Linux--基本指令2
  • 嵌入式开发工程师笔试面试指南-数电基础