【剑斩OFFER】算法的暴力美学——串联所有单词的字串

一、题目描述

二、算法原理

我们可以看上面这个例子,我们记录s数组每个字母的个数,假设s数组在一段区间内的a、b、c的个数都为1,而和我们目标数组word的每个字母的个数相同,那么无论s数组的这段区间的a、b、c字母怎么排列都是我们目标的数组。

我们可以定义两个哈希表来记录每个单词的个数,又定义一个 count 来记录s组织的有效字母,有效字母就是:if:hash1[ a ] <= hash[ a ] ,他是属于 word 字母中的其中一个,此时就是有效字母;我们记录的word字符串,所以当 right 遍历的字母大于word的长度时,我们就要移动 left 的指向的字母了,使他变得合法,同时也要把left指向的字母从hash1中移除。此时right往后遍历就行,不用返回到和 left 指向的字母一样的下标,因为left到right之间的字母都没有符合word,所以就算right回到跟left指向的字母的下标一样,然后重新遍历,当遍历到和上次的right指向的字母的下标时,此时也是不符合word字符串的,所以当left要更新时,right 往后遍历就行。只要 count 等于word的字母个数,此时就是我们要的答案。

而本道题目跟上面的例子差不多一样的解法,只不过是要字母变成了单词罢了,细节:

因为我们要遍历的是单词,又因为words中的所有单词的长度都一样,我们不知道从s中的那个下标有可能够成符合条件单词的下标,所以我们我们要遍历words中的单词的长度遍s,不可能大于这个长度,当大于这个长度时表明前面的单词不要了。

因为我们遍历的是单词所以right每次移动 words 中的单词长度。

三、代码实现

cpp 复制代码
class Solution {
public:
    vector<int> findSubstring(string s, vector<string>& words) {
        unordered_map<string,int> mp;
        for(auto& e : words)
        {
            mp[e]++;
        }

        int len = words[0].size();
        int size = words.size();

        vector<int> ret;

        for(int i = 0; i < len;i++)
        {
            int left = i;
            int count = 0;
            unordered_map<string,int> mp1;
            for(int right = i; right < s.size();right += len)
            {
                string str;
                str = s.substr(right,len);
                mp1[str]++;
                if(mp1[str] && mp1[str] <= mp[str]) count++;
                while(right - left + 1 > size*len)
                {
                    string tmp;
                    tmp = s.substr(left,len);
                    if(mp1[tmp] <= mp[tmp]) count--;
                    mp1[tmp]--;
                    left += len;
                }
                if(count == size) ret.push_back(left);
            }
        }
        return ret;
    }
};
相关推荐
Dovis(誓平步青云)8 分钟前
《滑动窗口算法:从 “暴力遍历” 到 “线性高效” 的思维跃迁》
运维·服务器·数据库·算法
_OP_CHEN34 分钟前
【算法基础篇】(五十七)线性代数之矩阵乘法从入门到实战:手撕模板 + 真题详解
线性代数·算法·矩阵·蓝桥杯·c/c++·矩阵乘法·acm/icpc
天天爱吃肉821839 分钟前
【跨界封神|周杰伦×王传福(陶晶莹主持):音乐创作与新能源NVH测试,底层逻辑竟完全同源!(新人必看入行指南)】
python·嵌入式硬件·算法·汽车
im_AMBER40 分钟前
Leetcode 114 链表中的下一个更大节点 | 删除排序链表中的重复元素 II
算法·leetcode
xhbaitxl1 小时前
算法学习day38-动态规划
学习·算法·动态规划
多恩Stone1 小时前
【3D AICG 系列-6】OmniPart 训练流程梳理
人工智能·pytorch·算法·3d·aigc
历程里程碑1 小时前
普通数组----轮转数组
java·数据结构·c++·算法·spring·leetcode·eclipse
pp起床1 小时前
贪心算法 | part02
算法·leetcode·贪心算法
sin_hielo1 小时前
leetcode 1653
数据结构·算法·leetcode
2501_901147831 小时前
面试必看:优势洗牌
笔记·学习·算法·面试·职场和发展