博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
30. Substring with Concatenation of All Words
阅读量:5794 次
发布时间:2019-06-18

本文共 2297 字,大约阅读时间需要 7 分钟。

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).

分析

从s里面,找出由words里面的所有单词组成的字符子串(每个字符串仅出现一次),不要关注顺序。
该题和 3.Longest Substring Without Repeatition 类似,都是维护一个窗口去滑动,记左边界 left,右边界right
s长度 N
words里单个单词长度 M,words单词总数 L
那么对s遍历的右边界 last = N - M + 1
在 hashmap 中存入 words 中的每个单词,key是单词,value单词出现在words中的index。 O(L)
创建一个二维数组 table [2][L]
0行:记录words中每个单词出现的次数。 O(L)
1行:记录扫描时候,left和right之间窗口中,包含words的单词出现次数
创建一个一维数组 smapping,遍历s,记录每个单词是否在 workds中。如果存在,则放入在words中的index;如果不存在,则为-1。 O(N)
算法GIF解释:
567993-20170204171731917-611046439.gif

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
class 
Solution {
public
:
    
vector<
int
> findSubstring(string s, vector<string>& words) {
        
int 
N = s.size();
        
int 
M = words[0].size();
        
int 
L = words.size();
        
int 
last = N - M + 1;
        
vector<
int
> result;
        
unordered_map<string, 
int
> mapping;
        
vector<vector<
int
>> table(2,vector<
int
> (L));
 
        
vector<
int
> smapping(last, -1);
 
        
int 
index = 0, failures = 0;
        
for 
(
int 
i = 0; i < L; ++i) {
            
auto word = mapping.find(words[i]);
            
if 
(word == mapping.end()) {
                
failures++;
                
mapping.insert({ words[i], index++ });
                
word = mapping.find(words[i]);
            
}
            
table[0][word->second]++;
        
}
 
        
for 
(
int 
i = 0; i < last; ++i) {
            
auto word = mapping.find(s.substr(i, M));
            
if 
(word != mapping.end()) {
                
smapping[i] = word->second;
            
}
            
else 
{
                
smapping[i] = -1;
            
}
        
}
 
        
for 
(
int 
i = 0; i < M; ++i) {
            
int 
currentFailures = failures;
            
fill(table[1].begin(), table[1].end(), 0);
            
int 
L = i, R = i;
            
while 
(R < last) {
                
while 
(currentFailures != 0 && R < last) {
                    
if 
(smapping[R] != -1 && ++table[1][smapping[R]] == table[0][smapping[R]]) {
                        
currentFailures--;
                    
}
                    
R += M;
                
}
 
                
while 
(currentFailures == 0 && L < R) {
                    
if 
((R - L) / M == words.size()) {
                        
result.push_back(L);
                    
}
                    
if 
(smapping[L] != -1 && --table[1][smapping[L]] == table[0][smapping[L]] - 1) {
                        
currentFailures++;
                    
}
                    
L += M;
                
}
            
}
        
}
        
return 
result;
    
}
};
 

附件列表

 

转载于:https://www.cnblogs.com/zhxshseu/p/5df501ce21791b3c3cf3229bb03f5b23.html

你可能感兴趣的文章
开放产品开发(OPD):OPD框架
查看>>
【Java】操作Sqlite数据库
查看>>
做好PM的几个要素
查看>>
Flex通过Blazeds利用Remoteservice与后台java消息推送
查看>>
Vim的使用 区域选择
查看>>
.Net 中的反射(查看基本类型信息) - Part.2
查看>>
[转]C#中捕捉对话框的文本内容 EnumChildWindows
查看>>
AutoResetEvent和ManualResetEvent用法
查看>>
premake在Ubuntu和GCC环境下创建简单的C++工程
查看>>
A listing of Datagrid articles from other resource sites:
查看>>
软件包管理 之 RPM HOWTO 中译本介绍
查看>>
步步为营 .NET 代码重构学习笔记 一、为何要代码重构
查看>>
步步为营 SharePoint 开发学习笔记系列 十、SharePoint web service 开发(下)
查看>>
[转]iOS SDK:iOS调试技巧
查看>>
msgpack和protobuf的对比
查看>>
滑动导航栏+滚动页面
查看>>
【Text Editor】文本编辑器:Sublime Text
查看>>
VSTO之旅系列(三):自定义Excel UI
查看>>
Linux高性能服务器编程
查看>>
xBIM IFC 输出 Excel 报表
查看>>