# LeetCode -- question 30 -- concatenate the substrings of all words

Concatenate substrings of all words

Difficulty: difficulty

Given a string s and some words of the same length. Find out the starting position of a substring in s that can be formed by concatenation of all words in words.

Note that the substring should exactly match the words in words, and there should be no other characters in the middle, but the sequence of words in words should not be considered.

Example 1:

```Input:
s = "barfoothefoobarman",
words = ["foo","bar"]
Output: [0,9]
Explanation:
The substrings starting with indexes 0 and 9 are "barfoo" and "foobar", respectively.
The order of output is not important, and [9,0] is also a valid answer.
```

Example 2:

```Input:
s = "wordgoodgoodgoodbestword",
words = ["word","good","best","word"]
Output: []```

Topic analysis:

The difficulty of this topic is that it has many words to match, if a single word is a direct violent match or KMP match. If there are more than one word, it is not to consider the word order problem. Along this way, we think of backtracking and violent matching. I know I can't handle large matching, but I still write. The result didn't disappoint me. The running time-out, function realization and efficiency were too low. According to the idea of the great God, I wrote it again. Here, the sorting is converted to hash table query, which greatly improves the efficiency. In addition, the total value matching of ASCII code improves the efficiency. The general idea is to store words in the hash table first, then initialize the ASCII total value of the total words length, and then traverse to match. If the ASCII total value does not match, the next one will be directly matched. If it is equal, then further matching will be carried out. If the hash table query is used, the matching will be successful.

Reference code:

```#include "iostream"
#include "vector"
#include "string"
#include "unordered_map"
#include "deque"

using namespace std;

//Backtracking plus violence matching
//class Solution {
//public:
//	vector<int> res;
//	vector<int> findSubstring(string s, vector<string>& words) {
//		if (s.empty() || words.empty())
//			return res;
//
//		q_pl(words, 0, s);
//		return res;
//	}
//
//	void q_pl(vector<string>& s, int index, const string& ss)
//	{
//		if (index == s.size())
//		{
//			string my_str;
//			for (int i = 0; i < s.size(); i++)
//			{
//				my_str += s[i];
//			}
//			for (int j = 0; j < ss.size(); ++j)
//			{
//				int k = 0;
//				if (ss[j] == my_str[k])
//				{
//					for (; k < my_str.size(); ++k)
//					{
//						if (ss[j+k] != my_str[k])
//							break;
//					}
//					if (k == my_str.size())
//						res.push_back(j);
//				}
//			}
//			return;
//		}
//
//		for (int i = index; i < s.size(); i++)
//		{
//			if (is_change(s, index, i))
//			{
//				swap(s[index], s[i]);
//				q_pl(s, index + 1, ss);
//				swap(s[index], s[i]);
//			}
//		}
//	}
//
//	bool is_change(const vector<string>& s, int begin, int end)
//	{
//		if (begin >= s.size())
//		{
//			return false;
//		}
//
//		for (int i = begin; i < end; i++)
//		{
//			if (s[i] == s[end])
//				return false;
//		}
//		return true;
//	}
//};

class Solution{
public:
vector<int> findSubstring(string s, vector<string>& words)
{
vector<int> res;
//Considering that the string is empty, the matching character length is greater than the matched character length
if (s.empty() || words.empty() || s.size() < words.size()*words.size()) return res;

//Because each group of words is equal in length, the total length can be calculated by multiplying the length of words
int lens = words.size()*words.size();
int target = 0;    //Match string ASCII value
int cur_val = 0;   //ASCII value of matched string
unordered_map<string, int> my_map;
//Calculate the total ASCII sum of the match length
for (auto i:words)
{
my_map[i]++;  //By the way, initialize the hash table
for (auto j : i)
target += j;
}
//Calculate the ASCII value of the first matched string
for (int k = 0; k < lens; k++) cur_val += s[k];
int y = 0;
for (int x = 0; x <= s.size() - words.size()*words.size(); ++x)
{
//If the string ASCII value does not match, the string must not match
if (cur_val != target)
{
cur_val = cur_val - s[x] + s[lens + x];
continue;
}
//Further confirmation of string match
unordered_map<string, int> temp_map(my_map);//Create a temporary string hash table for querying
//From the x position, one word matches
for (y = x; y < x + lens; y += words.size())
{
//If the words match, the hash table is 0
if ((temp_map[s.substr(y, words.size())])-- == 0) break;
}
//Description after matching, record the location
if (y == x + lens) res.push_back(x);
//Update the ASCII value of the next matched string
cur_val = cur_val - s[x] + s[lens + x];
}
return res;
}
};

int main()
{
Solution solution;
string str = "wordgoodgoodgoodbestword";
vector<string> words = { "word", "good", "best", "good" };
vector<int> res;
res = solution.findSubstring(str, words);

for (int i = 0; i < res.size(); i++)
{
cout << res[i] << endl;
}

system("pause");
return 0;
}
```

Tags: ascii

Posted on Fri, 12 Jun 2020 05:04:55 -0400 by fanfavorite