每日一题day1(Leetcode 76最小覆盖子串)

1.题目解析

1.该题"讲人话"就是在一个字符串s中找到一个最短的能够涵盖子串所有字符的子串

2.解法

  1. 解法1(暴力枚举+hash表)
cpp 复制代码
class Solution {
public:
    string minWindow(string s, string t) {
        int m = s.size();
        int n = t.size();
        if (m < n)
            return "";                 // 解决实例3的特殊情况
        unordered_map<char, int> need; // 统计t中的字符需要的次数
        for (auto c : t) {
            need[c]++;
        }
        int required = need.size(); // 记录字符种类
        int len = INT_MAX;
        int start = 0; // 记录子串开始位置为后续返回字符串奠定基础
        for (int i = 0; i < m; i++) {
            int matched = 0;
            unordered_map<char, int> window;
            for (int j = i; j < m; j++) {
                char c = s[j];
                if (need.count(c)) { // 筛除不必要的元素
                    window[c]++;     // 记录子串中字符出现次数
                    if (window[c] == need[c])
                        matched++; // 达到目标
                }
                if (matched == required) {
                    int currentlen = j - i + 1;

                    if (currentlen < len) {
                        len = currentlen;
                        start = i; // 更新位置
                    }
                    break;
                }
            }
        }
        return len == INT_MAX ? "" : s.substr(start, len);
    }
};

虽然这种解题方法容易想但是作为一道困难题是绝对不可能让你暴力(O(n^2))过的,这个时候我们就需要在暴力的基础上进行优化
我们此处可以选择使用滑动窗口的方式对该问题进行优化

  1. 解法2(滑动窗口+手动hash)
cpp 复制代码
class Solution {
public:
    string minWindow(string s, string t) {

        int hash1[128] = {0}; // 统计t内字符出现的次数
        int kinds = 0;//统计有效字符个数
        for (auto ch : t) {
            if (hash1[ch]++ == 0)
                kinds++;
        }

        int hash2[128] = {0};
        int minlen = INT_MAX, begin = -1;
        for (int left = 0, right = 0, count = 0; right < s.size(); right++) {
            char in = s[right];
            if (++hash2[in] == hash1[in])//进窗口加维护count
                count++;
            while (count == kinds) {//判断
                if (right - left + 1 < minlen) {//更新结果
                    minlen = right - left + 1;
                    begin = left;
                }
                char out = s[left++];//出·窗口维护count
                if (hash2[out]-- == hash1[out])
                    count--;
            }
        }
        if (begin == -1)
            return "";
        else
            return s.substr(begin, minlen);
    }
};
相关推荐
小雅痞18 小时前
[Java][Leetcode middle] 3. 无重复字符的最长子串
java·开发语言·leetcode
qeen8718 小时前
【算法笔记】简单贪心
c++·笔记·算法·贪心算法
ting945200018 小时前
动手学深度学习(PyTorch版)深度详解(10): 优化算法 全解
人工智能·pytorch·深度学习·算法
ulias21218 小时前
leetcode热题 - 5
数据结构·算法·leetcode
Funny_AI_LAB19 小时前
Naval最新播客谈“氛围编码”:Vibe Coding 开启“一人独角兽”时代
人工智能·算法·语言模型·agi
如何原谅奋力过但无声19 小时前
【灵神高频面试题合集04-05】二分查找
数据结构·python·算法·leetcode
我不是懒洋洋19 小时前
【数据结构】排序算法(直接插入排序、希尔排序、选择排序、堆排序、冒泡排序、快速排序、归并排序、计数排序)
c语言·数据结构·c++·经验分享·算法·排序算法
MediaTea19 小时前
ML:逻辑回归的基本原理与实现
人工智能·算法·机器学习·数据挖掘·逻辑回归
超级码力6661 天前
【Latex文件架构】Latex文件架构模板
算法·数学建模·信息可视化
穿条秋裤到处跑1 天前
每日一道leetcode(2026.04.29):二维网格图中探测环
算法·leetcode·职场和发展