原题链接在这里: https://leetcode.com/problems/substring-with-concatenation-of-all-words/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.

For example, given:
s: "barfoothefoobarman"
words: ["foo", "bar"]

You should return the indices: [0,9].
(order does not matter).

题解:

类似Minimum Window Substring里有总结.

需要先生成global map计算words中每个word 的frequency. 快慢指针围成的window里也有个小的map计算map中出现在words的word, 当出现一个就count++.

当count是words数目和时就找到了一个结果.

检查当前词是否是words里的词时外层循环是多种取词方法,以例子来说就是分成:

|bar|foo|the|foo|bar|man

b|arf|oot|hef|oob|arm|an

ba|rfo|oth|efo|oba|rma|n

Note: s.substring(startIndex, endIndex) 其中的endIndex必须比s string本身长度小.

Time Complexity: O(s.length()).

Space: O(words.length). 

AC Java:

 1 class Solution {
 2     public List<Integer> findSubstring(String s, String[] words) {
 3         List<Integer> res = new ArrayList<Integer>();
 4         if(words == null || words.length == 0 || s == null || s.length() == 0){
 5             return res;
 6         }
 7         
 8         // 计算原有word frequency
 9         HashMap<String, Integer> hm = new HashMap<String, Integer>();
10         for(String word : words){
11             hm.put(word, hm.getOrDefault(word, 0)+1);
12         }
13         
14         int wordLen = words[0].length();
15         int count = 0;
16         int walker = 0;
17         
18         // 从等长word长度的开始到结尾挨个试,不需要再往后,因为那已经被长度开始里面的runner下一跳包括
19         for(int i = 0; i<wordLen; i++){
20             walker = i;
21             count = 0;
22             HashMap<String, Integer> windowHm = new HashMap<String, Integer>();
23             int max = s.length()-wordLen+1;
24             
25             for(int runner = walker; runner < max; runner += wordLen){
26                 String cur = s.substring(runner, runner+wordLen);
27                 if(hm.containsKey(cur)){
28                     // cur string在words中
29                     windowHm.put(cur, windowHm.getOrDefault(cur, 0)+1);
30                     if(windowHm.get(cur) <= hm.get(cur)){
31                         count++;
32                     }else{
33                         // cur这个词在window里出现的次数 多余 原来words中的次数
34                         while(windowHm.get(cur) > hm.get(cur)){
35                             String walkerStr = s.substring(walker, walker+wordLen);
36                             windowHm.put(walkerStr, windowHm.get(walkerStr)-1);
37                             if(windowHm.get(walkerStr) < hm.get(walkerStr)){
38                                 count--;
39                             }
40                             walker += wordLen;
41                         }
42                     }
43                     
44                     // 全部覆盖,向前移动walker
45                     if(count == words.length){
46                         res.add(walker);
47                         String walkerStr = s.substring(walker, walker+wordLen);
48                         windowHm.put(walkerStr, windowHm.get(walkerStr)-1);
49                         count--;
50                         walker += wordLen;
51                     }
52                 }else{
53                     // cur 不在words中
54                     windowHm.clear();
55                     count = 0;
56                     walker = runner+wordLen;
57                 }
58             }
59         }
60         
61         return res;
62     }
63 }

 

相关文章:

  • 2022-01-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-07-21
  • 2021-10-27
猜你喜欢
  • 2021-12-14
  • 2021-10-17
  • 2021-12-18
  • 2021-09-20
  • 2021-08-03
  • 2021-06-06
  • 2021-11-14
相关资源
相似解决方案