【剑斩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;
    }
};
相关推荐
人道领域8 分钟前
【LeetCode刷题日记】669.修剪二叉搜索树
开发语言·python·算法
2401_8685347832 分钟前
【无标题】
数据结构·r语言
Mr. zhihao1 小时前
Redis五大高级数据结构:原理-场景-底层-横向对比
数据结构·redis
QiLinkOS1 小时前
【从实验室到商业战场:发明专利如何重塑科技与企业的共生生态】
大数据·c语言·数据结构·c++·人工智能·单片机·算法
如此这般英俊1 小时前
手撕Claude Code—第一章 agent-loop
数据结构·人工智能·语言模型·自然语言处理
小白兔奶糖ovo2 小时前
【Leetcode】231. 2的幂
linux·算法·leetcode
xiaoxiaoxiaolll2 小时前
《Light: Science & Applications》合并BIC实现80倍阈值单模运行:超紧凑光子晶体激光器新突破
人工智能·算法·机器学习
Peter·Pan爱编程2 小时前
14. Lambda 表达式:随手可写的函数对象
c++·算法·ai编程
-To be number.wan2 小时前
算法日记 | 暴力枚举
学习·算法
s_w.h2 小时前
【 linux 】动静态库的制作
linux·运维·服务器·算法·bash