| 
1 | 1 | package g0001_0100.s0030_substring_with_concatenation_of_all_words  | 
2 | 2 | 
 
  | 
3 | 3 | // #Hard #String #Hash_Table #Sliding_Window #Top_Interview_150_Sliding_Window  | 
4 |  | -// #2023_07_03_Time_182_ms_(100.00%)_Space_37.9_MB_(100.00%)  | 
 | 4 | +// #2025_03_04_Time_14_ms_(98.62%)_Space_39.70_MB_(91.72%)  | 
5 | 5 | 
 
  | 
6 | 6 | class Solution {  | 
7 | 7 |     fun findSubstring(s: String, words: Array<String>): List<Int> {  | 
8 |  | -        val indices: MutableList<Int> = ArrayList()  | 
9 |  | -        if (words.size == 0) {  | 
10 |  | -            return indices  | 
 | 8 | +        val ans: MutableList<Int> = ArrayList<Int>()  | 
 | 9 | +        val n1 = words[0].length  | 
 | 10 | +        val n2 = s.length  | 
 | 11 | +        val map1: MutableMap<String, Int> = HashMap<String, Int>()  | 
 | 12 | +        for (ch in words) {  | 
 | 13 | +            map1.put(ch, map1.getOrDefault(ch, 0) + 1)  | 
11 | 14 |         }  | 
12 |  | -        // Put each word into a HashMap and calculate word frequency  | 
13 |  | -        val wordMap: MutableMap<String, Int> = HashMap()  | 
14 |  | -        for (word in words) {  | 
15 |  | -            wordMap[word] = wordMap.getOrDefault(word, 0) + 1  | 
16 |  | -        }  | 
17 |  | -        val wordLength = words[0].length  | 
18 |  | -        val window = words.size * wordLength  | 
19 |  | -        for (i in 0 until wordLength) {  | 
20 |  | -            // move a word's length each time  | 
 | 15 | +        for (i in 0..<n1) {  | 
 | 16 | +            var left = i  | 
21 | 17 |             var j = i  | 
22 |  | -            while (j + window <= s.length) {  | 
23 |  | -                // get the subStr  | 
24 |  | -                val subStr = s.substring(j, j + window)  | 
25 |  | -                val map: MutableMap<String, Int> = HashMap()  | 
26 |  | -                // start from the last word  | 
27 |  | -                for (k in words.indices.reversed()) {  | 
28 |  | -                    // get the word from subStr  | 
29 |  | -                    val word = subStr.substring(k * wordLength, (k + 1) * wordLength)  | 
30 |  | -                    val count = map.getOrDefault(word, 0) + 1  | 
31 |  | -                    // if the num of the word is greater than wordMap's, move (k * wordLength) and  | 
32 |  | -                    // break  | 
33 |  | -                    if (count > wordMap.getOrDefault(word, 0)) {  | 
34 |  | -                        j = j + k * wordLength  | 
35 |  | -                        break  | 
36 |  | -                    } else if (k == 0) {  | 
37 |  | -                        indices.add(j)  | 
38 |  | -                    } else {  | 
39 |  | -                        map[word] = count  | 
 | 18 | +            var c = 0  | 
 | 19 | +            val map2: MutableMap<String, Int> = HashMap<String, Int>()  | 
 | 20 | +            while (j + n1 <= n2) {  | 
 | 21 | +                val word1 = s.substring(j, j + n1)  | 
 | 22 | +                j += n1  | 
 | 23 | +                if (map1.containsKey(word1)) {  | 
 | 24 | +                    map2.put(word1, map2.getOrDefault(word1, 0) + 1)  | 
 | 25 | +                    c++  | 
 | 26 | +                    while (map2[word1]!! > map1[word1]!!) {  | 
 | 27 | +                        val word2 = s.substring(left, left + n1)  | 
 | 28 | +                        map2.put(word2, map2[word2]!! - 1)  | 
 | 29 | +                        left += n1  | 
 | 30 | +                        c--  | 
 | 31 | +                    }  | 
 | 32 | +                    if (c == words.size) {  | 
 | 33 | +                        ans.add(left)  | 
40 | 34 |                     }  | 
 | 35 | +                } else {  | 
 | 36 | +                    map2.clear()  | 
 | 37 | +                    c = 0  | 
 | 38 | +                    left = j  | 
41 | 39 |                 }  | 
42 |  | -                j = j + wordLength  | 
43 | 40 |             }  | 
44 | 41 |         }  | 
45 |  | -        return indices  | 
 | 42 | +        return ans  | 
46 | 43 |     }  | 
47 | 44 | }  | 
0 commit comments