【剑斩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;
    }
};
相关推荐
零小陈上(shouhou6668889)9 分钟前
K-近邻算法 - lazy learning的代表
算法·近邻算法
有一个好名字15 分钟前
力扣-从字符串中移除星号
java·算法·leetcode
萧瑟其中~19 分钟前
二分算法模版——基础二分查找,左边界查找与右边界查找(Leetcode的二分查找、在排序数组中查找元素的第一个位置和最后一个位置)
数据结构·算法·leetcode
码上就好ovo21 分钟前
Atcoder Beginnner Contest 440
算法
高洁0128 分钟前
CLIP 的双编码器架构是如何优化图文关联的?(3)
深度学习·算法·机器学习·transformer·知识图谱
jllllyuz33 分钟前
MATLAB实现蜻蜓优化算法
开发语言·算法·matlab
iAkuya36 分钟前
(leetcode)力扣100 36二叉树的中序遍历(迭代递归)
算法·leetcode·职场和发展
wangwangmoon_light44 分钟前
1.1 LeetCode总结(线性表)_枚举技巧
算法·leetcode·哈希算法
码农小韩1 小时前
基于Linux的C++学习——动态数组容器vector
linux·c语言·开发语言·数据结构·c++·单片机·学习