|
2 | 2 |
|
3 | 3 | import java.util.*;
|
4 | 4 |
|
| 5 | +@SuppressWarnings("java:S127") |
5 | 6 | public class Solution {
|
6 | 7 | public List<Integer> findSubstring(String s, String[] words) {
|
7 |
| - List<Integer> output = new ArrayList<>(); |
8 |
| - if (s == null || words == null || s.length() == 0 || words.length == 0) { |
9 |
| - return output; |
| 8 | + List<Integer> indices = new ArrayList<>(); |
| 9 | + if (words.length == 0) { |
| 10 | + return indices; |
10 | 11 | }
|
11 |
| - int wordLen = words[0].length(), wordsCount = 0; |
12 |
| - Map<String, Integer> wordToCount = new HashMap<>(); |
| 12 | + // Put each word into a HashMap and calculate word frequency |
| 13 | + Map<String, Integer> wordMap = new HashMap<>(); |
13 | 14 | for (String word : words) {
|
14 |
| - wordToCount.put(word, wordToCount.getOrDefault(word, 0) + 1); |
15 |
| - wordsCount++; |
| 15 | + wordMap.put(word, wordMap.getOrDefault(word, 0) + 1); |
16 | 16 | }
|
17 |
| - int substringLen = wordLen * wordsCount; |
18 |
| - for (int start = 0; start < wordLen; start++) { |
19 |
| - Queue<String> queue = new LinkedList<>(); |
20 |
| - Map<String, Integer> substrWordToCount = new HashMap<>(); |
21 |
| - for (int lo = start, hi = start; hi <= s.length() - wordLen; hi += wordLen) { |
22 |
| - String word = s.substring(hi, hi + wordLen); |
23 |
| - if (!wordToCount.containsKey(word)) { |
24 |
| - queue = new LinkedList<>(); |
25 |
| - lo = hi + wordLen; |
26 |
| - substrWordToCount = new HashMap<>(); |
27 |
| - } else { |
28 |
| - int substrWordCount = substrWordToCount.getOrDefault(word, 0); |
29 |
| - if (substrWordCount >= wordToCount.get(word)) { |
30 |
| - while (!queue.peek().equals(word)) { |
31 |
| - String wordToRemove = queue.poll(); |
32 |
| - int count = substrWordToCount.get(wordToRemove); |
33 |
| - if (count == 1) substrWordToCount.remove(wordToRemove); |
34 |
| - else substrWordToCount.put(wordToRemove, count - 1); |
35 |
| - lo += wordLen; |
36 |
| - } |
37 |
| - lo += wordLen; |
38 |
| - queue.poll(); |
| 17 | + int wordLength = words[0].length(); |
| 18 | + int window = words.length * wordLength; |
| 19 | + for (int i = 0; i < wordLength; i++) { |
| 20 | + // move a word's length each time |
| 21 | + for (int j = i; j + window <= s.length(); j = j + wordLength) { |
| 22 | + // get the subStr |
| 23 | + String subStr = s.substring(j, j + window); |
| 24 | + Map<String, Integer> map = new HashMap<>(); |
| 25 | + // start from the last word |
| 26 | + for (int k = words.length - 1; k >= 0; k--) { |
| 27 | + // get the word from subStr |
| 28 | + String word = subStr.substring(k * wordLength, (k + 1) * wordLength); |
| 29 | + int count = map.getOrDefault(word, 0) + 1; |
| 30 | + // if the num of the word is greater than wordMap's, move (k * wordLength) and |
| 31 | + // break |
| 32 | + if (count > wordMap.getOrDefault(word, 0)) { |
| 33 | + j = j + k * wordLength; |
| 34 | + break; |
| 35 | + } else if (k == 0) { |
| 36 | + indices.add(j); |
39 | 37 | } else {
|
40 |
| - substrWordToCount.put(word, substrWordCount + 1); |
41 |
| - } |
42 |
| - queue.offer(word); |
43 |
| - if (queue.size() == wordsCount) { |
44 |
| - output.add(lo); |
| 38 | + map.put(word, count); |
45 | 39 | }
|
46 | 40 | }
|
47 | 41 | }
|
48 | 42 | }
|
49 |
| - return output; |
| 43 | + return indices; |
50 | 44 | }
|
51 | 45 | }
|
0 commit comments