Skip to content

Commit 7c9e282

Browse files
committed
similar to wordbreak, but sorting words
1 parent 19880b9 commit 7c9e282

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
class Solution {
2+
/*
3+
Similar to word break solution. TC- O(b^d) since each word can be broken down
4+
on an avg in b parts.
5+
*/
6+
HashSet<String> set;
7+
public List<String> findAllConcatenatedWordsInADict(String[] words) {
8+
set = new HashSet<>();
9+
List<String> res = new ArrayList<>();
10+
if (words.length == 0 || words.length == 1) return res;
11+
for(String w: words) {
12+
set.add(w);
13+
}
14+
for(String w: words) {
15+
if (isConcat(w)) {
16+
res.add(w);
17+
}
18+
}
19+
return res;
20+
}
21+
22+
public boolean isConcat(String word) {
23+
int len = word.length();
24+
for(int i=1; i<len; i++) {
25+
String prefix = word.substring(0,i);
26+
String suffix = word.substring(i);
27+
if (set.contains(prefix) && (set.contains(suffix) || isConcat(suffix))) {
28+
return true;
29+
}
30+
}
31+
return false;
32+
}
33+
}
34+
35+
36+
/*
37+
String#hashCode() takes O(L) for the first computation.
38+
Because we use #substring() a lot here, we cannot utilize the hashCode cache,
39+
so dict.contains(word.substring(j, i)) in the inner loop takes O(L), which make it a triple loop over length L,
40+
that's O(L^3), and the overall is O(N*L^3).
41+
*/
42+
43+
class Solution {
44+
public List<String> findAllConcatenatedWordsInADict(String[] words) {
45+
List<String> res = new ArrayList<>();
46+
HashSet<String> set = new HashSet<>();
47+
// we can only make combinations from smaller words. Hence, we sort
48+
49+
Arrays.sort(words, new Comparator<String>() {
50+
public int compare(String s1, String s2) {
51+
return s1.length() - s2.length();
52+
}
53+
});
54+
// or Arrays.sort(words, (a,b) -> a.length() - b.length());
55+
HashSet<String> preWords = new HashSet<>();
56+
for(int i=0; i<words.length; i++) {
57+
if (canForm(words[i], preWords)) {
58+
res.add(words[i]);
59+
}
60+
preWords.add(words[i]);
61+
}
62+
return res;
63+
}
64+
65+
public boolean canForm(String word, HashSet<String> dict) {
66+
if (dict.isEmpty()) return false;
67+
boolean[] dp = new boolean[word.length() + 1];
68+
dp[0] = true;
69+
70+
for(int i=1; i<=word.length();i++) {
71+
for(int j=0; j<i; j++) {
72+
if(dp[j] && dict.contains(word.substring(j, i))) {
73+
dp[i] = true;
74+
break;
75+
}
76+
}
77+
}
78+
return dp[word.length()];
79+
}
80+
}

0 commit comments

Comments
 (0)