[LeetCode] 30. Substring with Concatenation of All Words 串联所有单词的子串
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.
Example 1:
Input:
s = "barfoothefoobarman",
words = ["foo","bar"]
Output: [0,9]
Explanation: Substrings starting at index 0 and 9 are "barfoor" and "foobar" respectively.
The output order does not matter, returning [9,0] is fine too.
Example 2:
Input:
s = "wordgoodstudentgoodword",
words = ["word","student"]
Output: []
给一个字符串和一单词列表,找出串联列表中所有单词的子串的起始位置。
解法:也就是要求出串联所有单词的子串,然后返回起始位置的坐标。
Java:
class Solution { public List<Integer> findSubstring(String s, String[] words) { final Map<String, Integer> counts = new HashMap<>(); for (final String word : words) { counts.put(word, counts.getOrDefault(word, 0) + 1); } final List<Integer> indexes = new ArrayList<>(); final int n = s.length(), num = words.length, len = words[0].length(); for (int i = 0; i < n - num * len + 1; i++) { final Map<String, Integer> seen = new HashMap<>(); int j = 0; while (j < num) { final String word = s.substring(i + j * len, i + (j + 1) * len); if (counts.containsKey(word)) { seen.put(word, seen.getOrDefault(word, 0) + 1); if (seen.get(word) > counts.getOrDefault(word, 0)) { break; } } else { break; } j++; } if (j == num) { indexes.add(i); } } return indexes; } }
Python:
class Solution(object): def findSubstring(self, s, words): """ :type s: str :type words: List[str] :rtype: List[int] """ result, m, n, k = [], len(s), len(words), len(words[0]) if m < n*k: return result lookup = collections.defaultdict(int) for i in words: lookup[i] += 1 # Space: O(n * k) for i in xrange(k): # Time: O(k) left, count = i, 0 tmp = collections.defaultdict(int) for j in xrange(i, m-k+1, k): # Time: O(m / k) s1 = s[j:j+k]; # Time: O(k) if s1 in lookup: tmp[s1] += 1 if tmp[s1] <= lookup[s1]: count += 1 else: while tmp[s1] > lookup[s1]: s2 = s[left:left+k] tmp[s2] -= 1 if tmp[s2] < lookup[s2]: count -= 1 left += k if count == n: result.append(left) tmp[s[left:left+k]] -= 1 count -= 1 left += k else: tmp = collections.defaultdict(int) count = 0 left = j+k return resultv
Python:
# Time: O(m * n * k), where m is string length, n is dictionary size, k is word length # Space: O(n * k) class Solution2(object): def findSubstring(self, s, words): """ :type s: str :type words: List[str] :rtype: List[int] """ result, m, n, k = [], len(s), len(words), len(words[0]) if m < n*k: return result lookup = collections.defaultdict(int) for i in words: lookup[i] += 1 # Space: O(n * k) for i in xrange(m+1-k*n): # Time: O(m) cur, j = collections.defaultdict(int), 0 while j < n: # Time: O(n) word = s[i+j*k:i+j*k+k] # Time: O(k) if word not in lookup: break cur[word] += 1 if cur[word] > lookup[word]: break j += 1 if j == n: result.append(i) return result
C++:
class Solution { public: vector<int> findSubstring(string s, vector<string>& words) { vector<int> res; if (s.empty() || words.empty()) return res; int n = words.size(), m = words[0].size(); unordered_map<string, int> m1; for (auto &a : words) ++m1[a]; for (int i = 0; i <= (int)s.size() - n * m; ++i) { unordered_map<string, int> m2; int j = 0; for (j = 0; j < n; ++j) { string t = s.substr(i + j * m, m); if (m1.find(t) == m1.end()) break; ++m2[t]; if (m2[t] > m1[t]) break; } if (j == n) res.push_back(i); } return res; } };
C++:
class Solution { public: vector<int> findSubstring(string s, vector<string>& words) { if (s.empty() || words.empty()) return {}; vector<int> res; int n = s.size(), cnt = words.size(), len = words[0].size(); unordered_map<string, int> m1; for (string w : words) ++m1[w]; for (int i = 0; i < len; ++i) { int left = i, count = 0; unordered_map<string, int> m2; for (int j = i; j <= n - len; j += len) { string t = s.substr(j, len); if (m1.count(t)) { ++m2[t]; if (m2[t] <= m1[t]) { ++count; } else { while (m2[t] > m1[t]) { string t1 = s.substr(left, len); --m2[t1]; if (m2[t1] < m1[t1]) --count; left += len; } } if (count == cnt) { res.push_back(left); --m2[s.substr(left, len)]; --count; left += len; } } else { m2.clear(); count = 0; left = j + len; } } } return res; } };
All LeetCode Questions List 题目汇总