赞
踩
题目描述:
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。查找所有满足条件的坐标:S中以该坐标开始的某个连续子串,包含了words中所有单词恰好一次。返回所有满足的坐标集合。
思路:假设S长度为n1,words长度为n2,words每个单词长度为n3。我们用一个map统计words中出现的所有单词,并且从S中任意i位置开始,考察连续n2个n3长度的子字符串:如果某个子字符串在map中没有出现,则i位置不符合;如果出现了,则map中减去相应单词的出现次数。一轮结束,如果map清空,则找到了一个符合条件的i位置,加入答案中。重复该步骤,直到获取所有满足的坐标。
时间复杂度为O((n1 - n2 * n3) * n2)。
代码:
- #include <bits/stdc++.h>
-
- using namespace std;
-
- class Solution {
- public:
- vector<int> findSubstring(string s, vector<string>& words) {
- int n2 = words.size();
- // Exceptional Case 1:
- if(n2 == 0){
- return vector<int>();
- }
- vector<int> ans;
- int n1 = s.length(), n3 = words[0].length();
- // debug
- // cout << "n1: " << n1 << ", n2: " << n2 << ", n3: " << n3 << endl;
- // Exceptional Case 2:
- if(n3 == 0){
- for(int i = 0; i <= n1; i++){
- ans.push_back(i);
- }
- return ans;
- }
- map<string, int> m1, m2;
- // save the words information
- for(int i = 0; i <= n2 - 1; i++){
- m1[words[i]]++;
- }
- for(int i = 0; i <= n1 - n2 * n3; i++){
- m2 = m1;
- for(int j = 0; j <= n2 - 1; j++){
- string str = s.substr(i + j * n3, n3);
- if(m2.count(str)){
- m2[str]--;
- if(m2[str] == 0){
- m2.erase(str);
- }
- }
- else{
- break;
- }
- }
- if(m2.size() == 0){
- ans.push_back(i);
- }
- }
- return ans;
- }
- };
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。