Description
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: []
问题描述
给定字符串s和字符串列表words(words中所有字符串的长度相等).找出s中的所有起始下标,使得s.substring(i)为words中每个单词的连接(每个单词有且一次)并且不包含任何交织的字符
问题分析
维护两个map
- wcount, 存储words中对应单词的个数
- seen, 在迭代下标i的过程中维护的map,存储当前见过的在words中的单词对应个数
思想
迭代下标,对每个下标维护seen,令某个在words中的单词为temp,若seen.get(temp) > wcount.get(temp),则终止迭代,否则计数增1,当计数等于words长度时,说明i有效,将i添加入结果中。此过程反复进行
解法
class Solution {
public List<Integer> findSubstring(String s, String[] words) {
List<Integer> res = new ArrayList();
if(s == null || words == null || words.length == 0) return res;
int n = s.length(), len = words[0].length(), num = words.length;
if(n < len * num) return res;
Map<String, Integer> wcount = new HashMap();
for(String word : words) wcount.put(word, wcount.getOrDefault(word, 0) + 1);
for(int i = 0;i <= n - num * len;i++){
Map<String, Integer> seen = new HashMap();
int j = 0;
for(;j < num;j++){
String str = s.substring(i + j * len, i + (j + 1) * len);
if(wcount.containsKey(str)){
seen.put(str, seen.getOrDefault(str, 0) + 1);
if(seen.get(str) > wcount.get(str)){
break;
}
}else{
break;
}
}
if(j == num){
res.add(i);
}
}
return res;
}
}