Skip to content

Commit 742ff52

Browse files
committed
new Solution().findSubstring("aaaaaaaa", new String[]{"aa", "aa", "aa"});
1 parent b0af713 commit 742ff52

File tree

1 file changed

+104
-0
lines changed

1 file changed

+104
-0
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package SubstringwithConcatenationofAllWords;
2+
3+
import java.util.*;
4+
import java.util.stream.Collectors;
5+
import java.util.stream.Stream;
6+
7+
/**
8+
* User: Danyang
9+
* Date: 1/29/2015
10+
* Time: 10:05
11+
*
12+
* You are given a string, S, and a list of words, L, that are all of the same length. Find all starting indices of
13+
* substring(s) in S that is a concatenation of each word in L exactly once and without any intervening characters.
14+
15+
For example, given:
16+
S: "barfoothefoobarman"
17+
L: ["foo", "bar"]
18+
19+
You should return the indices: [0,9].
20+
(order does not matter).
21+
*/
22+
public class Solution {
23+
/**
24+
* https://github.com/zhangdanyangg/LeetCode/blob/master/029%20Substring%20with%20Concatenation%20of%20All%20Words.py
25+
*
26+
* Algorithm:
27+
* Two pointers, sliding window, O(n*k)
28+
*
29+
* Notice:
30+
* 1. equal length
31+
* 2. when fail finding word, i need to go back to beginning
32+
* @param S
33+
* @param L
34+
* @return
35+
*/
36+
public List<Integer> findSubstring(String S, String[] L) {
37+
List<Integer> ret = new ArrayList<>();
38+
if(L.length<1 || S.length()<1)
39+
return ret;
40+
41+
Map<String, Long> Lmap_origin = Stream.of(L).collect(
42+
Collectors.groupingBy(e -> e, Collectors.counting())
43+
);
44+
45+
Map<String, Long> Lmap = new HashMap<>(Lmap_origin); // copy constructor
46+
List<String> workingWin = new ArrayList<>();
47+
48+
int i = 0;
49+
int k = L[0].length();
50+
int win_e = -1;
51+
while(i<S.length()) {
52+
if(workingWin.size()==L.length) {
53+
ret.add(win_e-workingWin.size()*k);
54+
int next = win_e-workingWin.size()*k+1;
55+
if(Lmap.containsKey(S.substring(next, Math.min(next+k, S.length())))) {
56+
i = next;
57+
workingWin.clear();
58+
win_e = -1;
59+
Lmap = new HashMap<>(Lmap_origin);
60+
continue;
61+
}
62+
}
63+
64+
65+
String word = S.substring(i, Math.min(i+k, S.length()));
66+
if(!Lmap.containsKey(word)) {
67+
if(workingWin.isEmpty())
68+
i++;
69+
else
70+
i = win_e-workingWin.size()*k+1;
71+
workingWin.clear();
72+
win_e = -1;
73+
Lmap = new HashMap<>(Lmap_origin);
74+
}
75+
else if(Lmap.get(word)>0) { // found remain
76+
win_e = i+k;
77+
Lmap.put(word, Lmap.get(word)-1);
78+
workingWin.add(word);
79+
i = win_e;
80+
}
81+
else {
82+
int indexOf = workingWin.indexOf(word);
83+
for(int j=0; j<=indexOf; j++) {
84+
String word2 = workingWin.get(j);
85+
Lmap.put(word2, Lmap.get(word2)+1);
86+
}
87+
win_e = i+k;
88+
Lmap.put(word, Lmap.get(word)-1);
89+
workingWin = workingWin.subList(indexOf+1, workingWin.size());
90+
workingWin.add(word);
91+
i = win_e;
92+
}
93+
}
94+
if(workingWin.size()==L.length) // when reaching end: test case Input: "a", ["a"]
95+
ret.add(win_e-workingWin.size()*k);
96+
return ret;
97+
}
98+
99+
public static void main(String[] args) {
100+
List<Integer> ret = new Solution().findSubstring("aaaaaaaa", new String[]{"aa", "aa", "aa"});
101+
List<Integer> expected = Arrays.asList(new Integer[]{0, 1, 2});
102+
assert ret.equals(expected);
103+
}
104+
}

0 commit comments

Comments
 (0)