力扣(LeetCode)30. 串联所有单词的子串(C++)

本文介绍了一种使用滑动窗口结合哈希表的方法来解决特定字符串匹配问题。通过维护两个哈希表来跟踪目标单词及其在当前滑动窗口内的出现次数,实现了高效查找所有符合要求的子串起始位置。
滑动窗口+哈希表

哈希表 tottottotwordswordswords 所有单词的出现次数。

维护滑动窗口,窗口长度 m×wm\times wm×wmmm 是单词数量 www是单词长度 , 窗口长度对应可行解的长度。哈希表 wdwdwd 维护滑动窗口内每个单词的出现次数。

维护有效串总数 cntcntcnt ,当 cnt=mcnt=mcnt=m 时,找到一个可行解。当右窗口右移,加入的单词是需要的,cnt++cnt++cnt++ , 当左窗口右移,移除的单词是需要的,cnt−−cnt--cnt 。 对照 wdwdwdtottottot 判断单词是否需要 。

提示 : 滑动窗口达到最大长度后,维护左窗口。

sss 分成 www 组,起点从 000w−1w-1w1 ,遍历每一组,得到答案。

class Solution {
public:
    vector<int> findSubstring(string s, vector<string>& words) {//字符串哈希
        vector<int> ans;
        if(words.empty()) return ans;
        unordered_map<string,int> tot;
        for(auto &x:words) tot[x]++;
        int n = s.size(),m = words.size(),w = words[0].size();
        for(int i = 0;i<w;i++){
            int cnt = 0;
            unordered_map<string,int> wd;
            for(int j = i ;j<=n;j+=w){
                if(j >= i + m*w){//滑动窗口满了,维护左窗口
                    auto s1 = s.substr(j-m*w,w);
                    wd[s1]--;
                    if(tot[s1]>wd[s1]) cnt--;//减去了有效串
                }
                auto s2 = s.substr(j,w);
                wd[s2]++;
                if(tot[s2]>=wd[s2]) cnt++;//增加了有效串
                if(m == cnt) ans.push_back(j-(m-1)*w);
            }
        }
        return ans;
    }
};
  1. 时间复杂度 : O(w×n)O(w\times n)O(w×n)nnn 是字符串 sss 的长度, www 是单词长度。遍历 www 组的时间复杂度 O(w)O(w)O(w) ,每组 nw\dfrac n wwn 个单词的时间复杂度 O(nw)O(\dfrac n w)O(wn) ,遍历字母得到单词的时间复杂度 O(w)O(w)O(w) ,三者是相乘关系,总时间复杂度 O(w×n)O(w\times n)O(w×n)
  2. 空间复杂度 : O(w×m)O(w\times m)O(w×m)mmm 是单词总数 wordswordswords 的长度 , www 是单词长度。 哈希表 tottottot 的空间复杂度是 O(w×m)O(w\times m)O(w×m) , 哈希表 tottottot 的空间复杂度是 O(w×m)O(w\times m)O(w×m) ,总空间复杂度是 O(2×w×m)O(2\times w\times m)O(2×w×m) 。 忽略常数空间复杂度 O(w×m)O(w\times m)O(w×m)
博主致语

理解思路很重要!
欢迎读者在评论区留言,作为日更博主,看到就会回复的。

AC

AC

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清墨韵染

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值