[LC优选算法#4] 滑动窗口 | 串联所有单词的⼦串 | 最⼩覆盖⼦串

滑动窗口专题:

LC优选算法#2 滑动窗口 | 长度最小的子数组 | 无重复字符的最长子串 | 最大连续1的个数

LC优选算法#3 滑动窗口 | 将x减到0的最⼩操作数 | ⽔果成篮 | 字⺟异位词

1. 串联所有单词的⼦串

串联所有单词的⼦串

解题思路:滑动窗口 O(len * N)

研究对象是连续区间,可以尝试用滑动窗口的思想解决。

题目中限定了每个字符串的长度相同,如果把一个个字符串当作字母来处理,就可以转化为「字符串中所有的字⺟异位词」(Leetcode438)。

如果words数组中有n个单词,每个单词长度为len

  • 首先需要用一个哈希表 hash1 存储words数组中字符串的种类和个数,另外一个哈希表 hash2 用于存储滑动窗口中截取子串内部单词的种类和个数。
  • 窗口内部,用双指针划分窗口内的每个长度为 len 的单词,放入 hash2 中,再用count 来统计窗口中的有效单词。最后通过比对 countn 是否相同来更新结果。

那么滑动窗口的起点应该怎么确定呢?通过观察发现,单词的长度 len 是固定统一的,那么仅需从第一个单词的每一位 向后使用一次滑动窗口,就可以把所有情况都包括在内了:

整体思路如下:

由于总共需要遍历len次数组,因此时间复杂度为O(len * N)

cpp 复制代码
class Solution {
public:
    vector<int> findSubstring(string s, vector<string>& words)
    {
        unordered_map<string, int> hash1; //样板
        vector<int> ret;

        for(auto& str : words)
        {
            hash1[str]++;
        }

        int n = words.size(); //字符串个数
        int len = words[0].size(); //字符串单位长度

        for(int i=0; i<len; i++)
        {
            unordered_map<string, int> hash2;
            int count = 0;
            for(int left=i, right=i; right+len<=s.size(); right+=len)
            {
                //进窗口+维护count
                string in = s.substr(right, len);
                hash2[in]++;
                if(hash1.count(in) && hash2[in] <= hash1[in])
                {
                    count++;
                }

                //判断
                if(right - left + 1 > len * n)
                {
                    //出窗口+维护count
                    string out = s.substr(left, len);
                    //单词存在且单词个数未满 == 有效单词
                    if(hash1.count(out) && hash2[out] <= hash1[out])
                    {
                        count--;
                    }

                    hash2[out]--;
                    left += len;
                }

                //更新结果
                if(count == n)
                {
                    ret.push_back(left);
                }
            }
        }

        return ret;
    }
};

2. 最⼩覆盖⼦串

最⼩覆盖⼦串

解题思路:滑动窗口 O(N)

研究对象是连续区间,可以尝试用滑动窗口的思想解决。

  • 使用一个哈希表hash1统计目标子串中的字符的个数,kinds变量统计hash1中字符的种类。
  • 窗口内部,一个哈希表hash2统计当前窗口中的字符个数。count变量统计hash2中有效字符的种类。最后通过比对countkinds来更新结果。

一些细节 :由于题目所求的是最小子串,因此可以用substr库函数截取最小子串,这其中需要提供子串的起始下标begin和长度len作为参数,因此需要在更新结果时记录。

两个指针在最坏情况下近似于分别遍历一次子串,相当于N*N,因此时间复杂度为O(N)

cpp 复制代码
class Solution {
public:
    string minWindow(string s, string t)
    {
        int hash1[128] = {0};
        int kinds = 0;
        for(auto ch : t)
        {
            if(hash1[ch] == 0)
            {
                kinds++;
            }
            hash1[ch]++;
        }

        int begin = -1;
        int len = INT_MAX;

        int hash2[128] = {0};
        for(int left=0, right=0, count=0; right < s.size(); right++)
        {
            //进窗口
            char in = s[right];
            hash2[in]++;
            if(hash2[in] == hash1[in])
            {
                count++;
            }

            //判断
            while(count == kinds)
            {                
                //更新结果
                if(right - left + 1 < len)
                {
                    begin = left;
                    len = right - left + 1;
                }
                
                //出窗口
                char out = s[left];
                if(hash2[out] == hash1[out])
                {
                    count--;
                }
                
                hash2[out]--;
                left++;
            }
        }
       
        if(begin == -1) return "";
        return s.substr(begin, len);
    }
};

// 本期内容就到这里啦,如果对你有帮助,请三连支持!我是青云,我们下期见^_~

相关推荐
devilnumber1 小时前
Java 二分查找(二分算法)详解 + 实战运用 + 核心坑点
java·开发语言·算法
洛水水1 小时前
【力扣100题】84.字符串解码
算法·leetcode·职场和发展
MicroTech20252 小时前
量子隐形传态路线的瓶颈与突破,微算法科技(MLGO)以技术创新助力量子通信长距离组网
科技·算法·量子计算
洛水水2 小时前
【力扣100题】89.下一个排列
数据结构·算法·leetcode
洛水水2 小时前
【力扣100题】90.寻找重复数
算法·leetcode·职场和发展
鱼子星_2 小时前
【数据结构】排序的拓展——快速排序的生态多样性与归并排序沾染文件操作
c语言·数据结构·算法
alphaTao2 小时前
LeetCode 每日一题 2026/6/8-2026/6/14
算法·leetcode
KaMeidebaby2 小时前
卡梅德生物技术快报|噬菌体展示文库构建全流程解析 | 大豆球蛋白纳米抗体筛选实践
人工智能·python·tcp/ip·算法·机器学习
CC数学建模2 小时前
2026年第十六届APMCM 亚太地区大学生数学建模竞赛(中文赛项)赛题B题:高性能芯片热管理系统的优化问题完整思路、代码、模型、文章,全网首发高质量分享!
python·算法·数学建模