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


    滑动窗口+哈希表

    哈希表 t o t tot tot w o r d s words words 所有单词的出现次数。

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

    维护有效串总数 c n t cnt cnt ,当 c n t = m cnt=m cnt=m 时,找到一个可行解。当右窗口右移,加入的单词是需要的, c n t + + cnt++ cnt++ , 当左窗口右移,移除的单词是需要的, c n t − − cnt-- cnt 。 对照 w d wd wd t o t tot tot 判断单词是否需要 。

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

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

    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    1. 时间复杂度 : O ( w × n ) O(w\times n) O(w×n) n n n 是字符串 s s s 的长度, w w w 是单词长度。遍历 w w w 组的时间复杂度 O ( w ) O(w) O(w) ,每组 n w \dfrac n w wn 个单词的时间复杂度 O ( n w ) 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) m m m 是单词总数 w o r d s words words 的长度 , w w w 是单词长度。 哈希表 t o t tot tot 的空间复杂度是 O ( w × m ) O(w\times m) O(w×m) , 哈希表 t o t tot tot 的空间复杂度是 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

  • 相关阅读:
    解读服装行业生命周期
    系统编程之高效同步机制:条件变量
    【Spring源码】11. 我是注解类不?checkConfigurationClassCandidate()注解类判断方法详解
    【MyBatis】MyBatis 理论 40 问(二)
    Node.js通过ODBC访问PostgreSQL数据库
    踩坑npm install qrcodejs2和crypto-js
    全国计算机二级考试MySQL有必要考吗
    1003 Emergency
    测试开发——禅道
    Spark 内核(四) --------- Spark 任务调度机制
  • 原文地址:https://blog.csdn.net/Innocence02/article/details/127972070