[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 = "wordgoodgoodgoodbestword",
  words = ["word","good","best","word"]
Output: []

题意:

给定一个无重复单词的字典D,和一个长字符串S。找出S中的子串,该子串恰好是D中所有单词连接而成。

code

 1 /*
 2 Time: O(n * m ).  outter for loop to scan n items, inner for loop to scan m substrings
 3 Space: O(m)
 4 */
 5 class Solution {
 6       public List<Integer> findSubstring(String s, String[] words) {
 7         List<Integer> result = new ArrayList<>();
 8         // corner case
 9         if (words.length == 0 || s.length() == 0) return result;
10 
11         int wordLength = words[0].length();
12         int catLength = wordLength * words.length; // 求Concatenation长度。 因为题干说words中每个单词长度一致。
13         // corner case
14         if (s.length() < catLength) return result;
15 
16         Map<String, Integer> map = new HashMap<>();
17         for (String word : words)
18             map.put(word, map.getOrDefault(word, 0) + 1);   // words中有单词可能出现多次
19         
20                       // 终结到s.length() - catLength因为最后一部分catLength长度的串可能是一个valid Concatenation解
21         for (int i = 0; i <= s.length() - catLength; ++i) {
22             // deep copy
23             Map<String, Integer> checkingMap = new HashMap<>(map);
24 
25             for (int j = i; j < i + catLength; j = j + wordLength) {
26                 final String key = s.substring(j, j + wordLength);
27                 final int freq = checkingMap.getOrDefault(key, -1);
28 
29                 if (freq == -1 || freq == 0) break;
30 
31                 checkingMap.put(key, freq - 1);
32                 if (freq - 1 == 0) checkingMap.remove(key);
33             }
34 
35             if (checkingMap.size() == 0) result.add(i);
36         }
37         return result;
38     }
39 }
原文地址:https://www.cnblogs.com/liuliu5151/p/10717979.html