题目:

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

For example, given:
s: "barfoothefoobarman"
words: ["foo", "bar"]

You should return the indices: [0,9].
(order does not matter).

代码:

class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
vector<int> ret;
if ( words.empty() || s.empty() ) return ret;
const int len_w = words[].size(); // length of substring in words
const int end = words.size()*len_w; // total length of words
if ( end>s.size() ) return ret; // s size not enough
map<string, int> ori;
for ( int i=; i<words.size(); ++i )
{
if ( ori.find(words[i])==ori.end() ){
ori[words[i]] = ;
}
else{
ori[words[i]]++;
}
}
map<string, int> found;
int match_num = ;
int begin = ;
int i = ;
while ( i<s.size() )
{
//cout << "i:" << i << endl;
//cout << "m:" << match_num << endl;
//cout << "begin:" << begin << endl;
// match one substring in words
if ( ori.find(s.substr(i,len_w))!=ori.end() )
{
found[s.substr(i,len_w)]++;
// substring occur more than times in words
if ( found[s.substr(i,len_w)]>ori[s.substr(i,len_w)] )
{
found.clear();
match_num = ;
begin++;
i=begin;
continue;
}
i = i+len_w;
match_num++;
//cout << match_num << endl;
// match all substrings in words and push back a starting indices
if ( match_num==words.size() )
{
ret.push_back(i-end);
found.clear();
begin++;
i = begin;
match_num=;
}
}
// not match
else
{
found.clear();
match_num = ;
begin++;
i=begin;
}
}
return ret;
}
};

tips:

采用双指针技巧。

维护几个关键变量:

1. begin:可能的有效开始位置

2. match_num: 已经匹配上的words中的个数

3. ori: words中每个string,及其出现的次数

4. found: 当前已匹配的interval中,words中每个string,及其出现的次数

思路就是如果找到了匹配的某个string,i就不断向后跳;跳的过程中可能有两种情况不能跳了:

a) 下一个固定长度的子字符串不匹配了

b) 下一个固定长度的子字符串虽然匹配上了words中的一个,但是匹配的数量已经超过了ori中该string的数量

如果一旦不能跳了,就要把match_num和found归零;而且需要回溯到begin++的位置,开始新一轮的搜寻。

这里有个细节要注意:

直接用found.clear()就可以了,如果一个一个清零,会超时。

======================================

第二次过这道题,代码简洁了,一些细节回忆着也写出来了。保留一个ori用于判断的,再维护一个wordHit用于计数的;ori不能动,wordHit每次clear后默认的value=0。

class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
vector<int> ret;
if ( words.empty() ) return ret;
int len = words[].size();
if ( len*words.size()>s.size() ) return ret;
map<string, int> wordHit;
map<string ,int> ori;
for ( int i=; i<words.size(); ++i ) ori[words[i]]++;
for ( int i=; i<=s.size()-len*words.size(); ++i )
{
wordHit.clear();
int j = i;
int hitCouts = ;
while ( hitCouts<words.size() && j<=s.size()-len )
{
// find word and not hit already
if ( ori.find(s.substr(j,len))==ori.end() ) break;
if ( wordHit[s.substr(j,len)]<ori[s.substr(j,len)] )
{
wordHit[s.substr(j,len)]++;
j += len;
hitCouts++;
}
else { break; }
}
// if hits all words
if ( hitCouts==words.size() ) ret.push_back(i);
}
return ret;
}
};

【Substring with Concatenation of All Words】cpp的更多相关文章

  1. 【Flatten Binary Tree to Linked List】cpp

    题目: Given a binary tree, flatten it to a linked list in-place. For example,Given 1 / \ 2 5 / \ \ 3 4 ...

  2. 【Binary Tree Zigzag Level Order Traversal】cpp

    题目: Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from lef ...

  3. 【Binary Tree Level Order Traversal II 】cpp

    题目: Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from ...

  4. 【Kth Smallest Element in a BST 】cpp

    题目: Given a binary search tree, write a function kthSmallest to find the kth smallest element in it. ...

  5. 【Search in Rotated Sorted Array II 】cpp

    题目: Follow up for "Search in Rotated Sorted Array":What if duplicates are allowed? Would t ...

  6. 【Letter Combinations of a Phone Number】cpp

    题目: Given a digit string, return all possible letter combinations that the number could represent. A ...

  7. 【Remove Duplicates from Sorted List II 】cpp

    题目: Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct  ...

  8. 【Remove Duplicates from Sorted Array II】cpp

    题目: Follow up for "Remove Duplicates":What if duplicates are allowed at most twice? For ex ...

  9. 【leetcode】Substring with Concatenation of All Words

    Substring with Concatenation of All Words You are given a string, S, and a list of words, L, that ar ...

随机推荐

  1. jmter安装配置

    一 JMeter 简介 JMeter 它是Apache组织的开放源代码项目,它是现在比较流行的功能和性能测试的工具.JMeter requires a fully compliant JVM 7 or ...

  2. 2018.9.9 Tomcat是怎样运行的

    一. Servlet容器是怎样工作的 一个Servlet容器是一个复杂的系统.然而,对于处理对Servlet的请求,Servlet容器主要做三件事情: 1. 创建请求对象,并设置所调用的Servlet ...

  3. SecureCRT 设置

  4. scrapy Pipeline 练习

    class WeatherPipeline(object): def process_item(self, item, spider): print(item) return item #插入到red ...

  5. N76E003---看门狗

    看门狗的设置 比较简单,根据芯片手册上的说明进行设置.值得一提的是设置看门狗的寄存器是保护寄存器,所以在写寄存器的时候要解除保护 void wtd_init(void) { TA=0xAA; TA=0 ...

  6. device not ready cuda

    问题描述: CUDA: 使用cudaEventElapsedTime时返回device not ready error 强调下我是用谷歌大神搜索到的结构哦! http://stackoverflow. ...

  7. centos安装django

    1.如果默认安装的是python2.6,先升级至python2.7 参考:http://www.cnblogs.com/tiger2soft/p/5677843.html 2.安装pip 先下载get ...

  8. ajax实现分页页签

    在一些搜索列表的页面中,我们会遇到一些需要处理页签的需求,一般这样的页面,要么是在JSP中处理,每次都跳页.这样做是个很方便的方法.但是如果页面上有很多和列表无关,每次都需要重新渲染是不是显得慢了一些 ...

  9. 17、SpringBoot------整合dubbo

    SpringBoot整合Dubbo+Zookeaper 1.安装运行zookeeper (1)下载zookeeper 官网:http://zookeeper.apache.org/ (2)解压缩 (3 ...

  10. WebSeal单点登陆

    WebSeal单点登陆 作为学习整理,部分内容来自网络和官方文档. LDAP LDAP可以看作一种数据库,分为客户端和服务端.服务端是用来存放资源,客户端用来操作资源.它是一种树形存储结构,遍历起来会 ...