每日算法之二十六:Substring with Concatenation of All Words

变相的字符串匹配

给定一个字符串,然后再给定一组相同长度的单词列表,要求在字符串中查找满足以下条件的起始位置:

1)从这个位置开始包含单词列表中所有的单词,且每个单词仅且必须出现一次。

2)在出现的过程中不能出现其他的干扰单词。

3)出现的位置可能有多个。

4)单词的出现顺序不做要求。

下面是一个例子:

S:"barfoothefoobarman"

L:"foo","bar"

位置0是出现位置,;两个单词均出现仅出现一次,且没有干扰。同样位置9也是满足的。

原题要求如下:

You are given a string, S,
and a list of words, L,
that are all of the same length. Find all starting indices of substring(s) in S that is a concatenation of each word in L exactly once and without any intervening characters.

思路如下:

首先初始化一个map容器,内含单词列表中出现的单词,以及单词出现的次数。把容器当做比较的模板。

string int
bar 1
foo 1

其次,指针i从0指向可能的最后位置,上例中是12,因为单词列表中总长度是6,在S中留下足够6的长度位置即可。因为中间干扰词的长度是不确定的,因此i只能是逐一的后移来寻找匹配的位置。

我们首先获得字符串中的第一个单词,bar。查看在上述的容器中是否有这个单词,如果没有,直接指针后移匹配下一个位置开始的单词。查找后是有的,因此我们把这个单词加入到一个新的map容器中,这个容器存储的是从当前指针位置开始满足单词列表的单词,这这个例子中就是bar在初始化的容器中存在,那么就把他加入新容器中。同时,统计次数也要递增,接下来查看这个单词在新容器中出现的次数是否小于等于初始化容器中的次数。如果大于说明这是错误的,也需要指针后移。

最后,当我们后移单词列表中指定个数的单词或者因为不匹配而终止从指针位置i开始的查找时,在循环外面我们要判断一下单词匹配的个数是否和单词列表中的次数一样,如果一样说明从当前指针的位置是匹配的。那么就把这个指针位置保存起来。如此循环往复即可。代码如下,顺着走一遍就明白了。

class Solution {
public:
    vector<int> findSubstring(string S, vector<string> &L) {
        map<string,int> words,cur;
        int wordNum = L.size();
        int wordLen = L[0].size();
        vector<int> res;
        for(int k = 0;k<wordNum;k++)
          words[L[k]]++;//初始化容器
        for(int i = 0;i<=static_cast<int>(S.length()-wordLen*wordNum);i++)
        {
          cur.clear();//每次使用之前要清空,这个容器是不断变化的
          int j;
          for(j = 0;j<wordNum;j++)
          {
            string word = S.substr(i+j*wordLen,wordLen);//获取这个单词
            if(words.find(word) == words.end())//这个单词不是单词列表中的
              break;
            cur[word]++;
            if(words[word]<cur[word])//出现的次数多了
              break;

          }
          if(j == wordNum)//这时候是匹配的
            res.push_back(i);
        }
        return res;
    }
};

每日算法之二十六:Substring with Concatenation of All Words,布布扣,bubuko.com

时间: 2025-01-20 14:51:50

每日算法之二十六:Substring with Concatenation of All Words的相关文章

每日算法之二十八:Longest Valid Parentheses

Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring. For "(()", the longest valid parentheses substring is "()", which has length = 2. Another example is &

每日算法之二十五:Divide Two Integers

Divide two integers without using multiplication, division and mod operator. 不使用乘法.除法和求模运算求两个数相除. class Solution { public: long long internalDivide(unsigned long long dividend,unsigned long long divisor) { if(dividend<divisor) return 0; int result =

每日算法之二十二:Swap Nodes in Pairs

Given a linked list, swap every two adjacent nodes and return its head. For example, Given 1->2->3->4, you should return the list as 2->1->4->3. Your algorithm should use only constant space. You may not modify the values in the list, on

每日算法之二十九:Search in Rotated Sorted Array

在一个经过旋转后的有序数组中查找一个目标元素. Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). You are given a target value to search. If found in the array return its index, otherwise return -1.

每日算法之二十:Generate Parentheses

Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses. For example, given n = 3, a solution set is: "((()))", "(()())", "(())()", "()(())", "()()()" 给出数字n,求

Powershell管理系列(二十六)PowerShell操作之批量导出&导入邮箱

-----提供AD\Exchange\Lync\Sharepoint\CRM\SC\O365等微软产品实施及外包,QQ:185426445.电话18666943750 项目中有时候做跨林邮箱迁移的时候,条件不成熟,比如安全考虑或者其他考虑,不能做双林信任,这样就提出了一个问题,历史邮件需要使用的话怎么办,一个简单高效的解决办法就是从源森林批量导出邮件为.pst文件,在批量导入到目的域森林,具体操作如下: 1.赋予管理账号邮件导入导出权限,命令如下: cls whoami New-Manageme

攻城狮在路上(叁)Linux(二十六)--- linux文件系统的特殊查看与操作

一.boot sector 与 super block的关系: 1.boot sector用于存放引导装载程序,占用1024个字节. 2.super block的大小也为1024字节. 3.若block大小为1k,则boot sector和super block各占一个block. 4.若block大于1K(2K/4K)时,则两者都位于第一个block中. 二.磁盘空间的浪费问题:暂不考虑. 三.利用GUN的parted命令进行分区行为: 因为fdisk不支持高于2TB的分区. 命令格式: pa

第一百二十六节,JavaScript,XPath操作xml节点

第一百二十六节,JavaScript,XPath操作xml节点 学习要点: 1.IE中的XPath 2.W3C中的XPath 3.XPath跨浏览器兼容 XPath是一种节点查找手段,对比之前使用标准DOM去查找XML中的节点方式,大大降低了查找难度,方便开发者使用.但是,DOM3级以前的标准并没有就XPath做出规范:直到DOM3在首次推荐到标准规范行列.大部分浏览器实现了这个标准,IE则以自己的方式实现了XPath. 一.IE中的XPath 在IE8及之前的浏览器,XPath是采用内置基于A

二十六:Struts2 和 spring整合

二十六:Struts2 和 spring整合 将项目名称为day29_02_struts2Spring下的scr目录下的Struts.xml文件拷贝到新项目的scr目录下 在新项目的WebRoot---->WEB-INF目录下新建一个目录lib,用于存放jar包(Struts2和spring整合所需jar包) 将项目名称为day29_02_struts2Spring,WebRoot---->WEB-INF下的lib目录下的所有jar包拷贝到新项目对应的位置,同时将spring的配置文件appl