Skip to content

Commit e2e6c25

Browse files
refactor 472
1 parent 7154945 commit e2e6c25

File tree

1 file changed

+144
-167
lines changed
  • src/main/java/com/fishercoder/solutions

1 file changed

+144
-167
lines changed

src/main/java/com/fishercoder/solutions/_472.java

Lines changed: 144 additions & 167 deletions
Original file line numberDiff line numberDiff line change
@@ -6,173 +6,150 @@
66
import java.util.List;
77
import java.util.Set;
88

9-
/**
10-
* 472. Concatenated Words
11-
*
12-
* Given a list of words, please write a program that returns all concatenated words in the given list of words.
13-
14-
A concatenated word is defined as a string that is comprised entirely of at least two shorter words in the given array.
15-
16-
Example:
17-
Input: ["cat","cats","catsdogcats","dog","dogcatsdog","hippopotamuses","rat","ratcatdogcat"]
18-
19-
Output: ["catsdogcats","dogcatsdog","ratcatdogcat"]
20-
21-
Explanation: "catsdogcats" can be concatenated by "cats", "dog" and "cats";
22-
"dogcatsdog" can be concatenated by "dog", "cats" and "dog";
23-
"ratcatdogcat" can be concatenated by "rat", "cat", "dog" and "cat".
24-
Note:
25-
The number of elements of the given array will not exceed 10,000
26-
The length sum of elements in the given array will not exceed 600,000.
27-
All the input string will only include lower case letters.
28-
The returned elements order does not matter.
29-
30-
*/
31-
329
public class _472 {
3310

34-
public static class Solution1 {
35-
private TrieNode root;
36-
private int maxWordLen;
37-
38-
public List<String> findAllConcatenatedWordsInADict(String[] words) {
39-
ResultType result = buildTrie(words);
40-
root = result.root;
41-
maxWordLen = result.maxWordLen;
42-
43-
List<String> validConcatenatedWords = new ArrayList();
44-
for (String word : words) {
45-
if (word == null || word.length() == 0) {
46-
continue;
47-
}
48-
remove(word, root);/** every word is comprised of every word itself, thus this word itself needs to be removed first for checking it*/
49-
int n = word.length();
50-
boolean[] dp = new boolean[n + 1];
51-
dp[0] = true;
52-
53-
for (int i = 1; i <= n; i++) {
54-
for (int j = 1; j <= i && j <= maxWordLen; j++) {
55-
if (!dp[i - j]) {
56-
continue;
57-
}
58-
59-
String subWord = word.substring(i - j, i);
60-
if (contains(subWord, root)) {
61-
dp[i] = true;
62-
break;
63-
}
64-
}
65-
}
66-
67-
if (dp[n]) {
68-
validConcatenatedWords.add(word);
69-
}
70-
undoRemove(word, root);
71-
}
72-
return validConcatenatedWords;
73-
}
74-
75-
public ResultType buildTrie(String[] words) {
76-
ResultType result = new ResultType();
77-
78-
TrieNode root = new TrieNode();
79-
int maxWordLen = 0;
80-
81-
for (String word : words) {
82-
maxWordLen = Math.max(maxWordLen, word.length());
83-
char[] chars = word.toCharArray();
84-
TrieNode node = root;
85-
for (int i = 0; i < chars.length; i++) {
86-
char c = chars[i];
87-
if (node.children[c - 'a'] == null) {
88-
node.children[c - 'a'] = new TrieNode();
89-
}
90-
node = node.children[c - 'a'];
91-
}
92-
node.isWord = true;
93-
}
94-
95-
result.root = root;
96-
result.maxWordLen = maxWordLen;
97-
return result;
98-
}
99-
100-
public class ResultType {
101-
int maxWordLen;
102-
TrieNode root;
103-
}
104-
105-
// Returns true if the word is in the trie.
106-
public boolean contains(String word, TrieNode root) {
107-
TrieNode node = root;
108-
for (int i = 0; i < word.length(); i++) {
109-
if (node.children[word.charAt(i) - 'a'] == null) {
110-
return false;
111-
}
112-
node = node.children[word.charAt(i) - 'a'];
113-
}
114-
return node.isWord;
115-
}
116-
117-
// mark that word on
118-
public void undoRemove(String word, TrieNode root) {
119-
TrieNode node = root;
120-
for (int i = 0; i < word.length(); i++) {
121-
node = node.children[word.charAt(i) - 'a'];
122-
}
123-
node.isWord = true;
124-
}
125-
126-
// mark that word off, we are not really deleting that word
127-
public void remove(String word, TrieNode root) {
128-
TrieNode node = root;
129-
for (int i = 0; i < word.length(); i++) {
130-
node = node.children[word.charAt(i) - 'a'];
131-
}
132-
node.isWord = false;
133-
}
134-
135-
class TrieNode {
136-
boolean isWord;
137-
TrieNode[] children = new TrieNode[26];
138-
139-
public TrieNode() {
140-
}
141-
}
142-
}
143-
144-
public static class Solution2 {
145-
public List<String> findAllConcatenatedWordsInADict(String[] words) {
146-
List<String> result = new ArrayList<>();
147-
Set<String> preWords = new HashSet<>();
148-
/**Words could only be formed by other words that are shorter than itself, so we sort them based on their lengths first.*/
149-
Arrays.sort(words, (s1, s2) -> s1.length() - s2.length());
150-
151-
for (int i = 0; i < words.length; i++) {
152-
if (canForm(words[i], preWords)) {
153-
result.add(words[i]);
154-
}
155-
preWords.add(words[i]);
156-
}
157-
158-
return result;
159-
}
160-
161-
boolean canForm(String word, Set<String> dict) {
162-
if (dict.isEmpty()) {
163-
return false;
164-
}
165-
boolean[] dp = new boolean[word.length() + 1];
166-
dp[0] = true;
167-
for (int i = 1; i <= word.length(); i++) {
168-
for (int j = 0; j < i; j++) {
169-
if (dp[j] && dict.contains(word.substring(j, i))) {
170-
dp[i] = true;
171-
break;
172-
}
173-
}
174-
}
175-
return dp[word.length()];
176-
}
177-
}
11+
public static class Solution1 {
12+
private TrieNode root;
13+
private int maxWordLen;
14+
15+
public List<String> findAllConcatenatedWordsInADict(String[] words) {
16+
ResultType result = buildTrie(words);
17+
root = result.root;
18+
maxWordLen = result.maxWordLen;
19+
20+
List<String> validConcatenatedWords = new ArrayList();
21+
for (String word : words) {
22+
if (word == null || word.length() == 0) {
23+
continue;
24+
}
25+
remove(word, root);/** every word is comprised of every word itself, thus this word itself needs to be removed first for checking it*/
26+
int n = word.length();
27+
boolean[] dp = new boolean[n + 1];
28+
dp[0] = true;
29+
30+
for (int i = 1; i <= n; i++) {
31+
for (int j = 1; j <= i && j <= maxWordLen; j++) {
32+
if (!dp[i - j]) {
33+
continue;
34+
}
35+
36+
String subWord = word.substring(i - j, i);
37+
if (contains(subWord, root)) {
38+
dp[i] = true;
39+
break;
40+
}
41+
}
42+
}
43+
44+
if (dp[n]) {
45+
validConcatenatedWords.add(word);
46+
}
47+
undoRemove(word, root);
48+
}
49+
return validConcatenatedWords;
50+
}
51+
52+
public ResultType buildTrie(String[] words) {
53+
ResultType result = new ResultType();
54+
55+
TrieNode root = new TrieNode();
56+
int maxWordLen = 0;
57+
58+
for (String word : words) {
59+
maxWordLen = Math.max(maxWordLen, word.length());
60+
char[] chars = word.toCharArray();
61+
TrieNode node = root;
62+
for (int i = 0; i < chars.length; i++) {
63+
char c = chars[i];
64+
if (node.children[c - 'a'] == null) {
65+
node.children[c - 'a'] = new TrieNode();
66+
}
67+
node = node.children[c - 'a'];
68+
}
69+
node.isWord = true;
70+
}
71+
72+
result.root = root;
73+
result.maxWordLen = maxWordLen;
74+
return result;
75+
}
76+
77+
public class ResultType {
78+
int maxWordLen;
79+
TrieNode root;
80+
}
81+
82+
// Returns true if the word is in the trie.
83+
public boolean contains(String word, TrieNode root) {
84+
TrieNode node = root;
85+
for (int i = 0; i < word.length(); i++) {
86+
if (node.children[word.charAt(i) - 'a'] == null) {
87+
return false;
88+
}
89+
node = node.children[word.charAt(i) - 'a'];
90+
}
91+
return node.isWord;
92+
}
93+
94+
// mark that word on
95+
public void undoRemove(String word, TrieNode root) {
96+
TrieNode node = root;
97+
for (int i = 0; i < word.length(); i++) {
98+
node = node.children[word.charAt(i) - 'a'];
99+
}
100+
node.isWord = true;
101+
}
102+
103+
// mark that word off, we are not really deleting that word
104+
public void remove(String word, TrieNode root) {
105+
TrieNode node = root;
106+
for (int i = 0; i < word.length(); i++) {
107+
node = node.children[word.charAt(i) - 'a'];
108+
}
109+
node.isWord = false;
110+
}
111+
112+
class TrieNode {
113+
boolean isWord;
114+
TrieNode[] children = new TrieNode[26];
115+
116+
public TrieNode() {
117+
}
118+
}
119+
}
120+
121+
public static class Solution2 {
122+
public List<String> findAllConcatenatedWordsInADict(String[] words) {
123+
List<String> result = new ArrayList<>();
124+
Set<String> preWords = new HashSet<>();
125+
/**Words could only be formed by other words that are shorter than itself, so we sort them based on their lengths first.*/
126+
Arrays.sort(words, (s1, s2) -> s1.length() - s2.length());
127+
128+
for (int i = 0; i < words.length; i++) {
129+
if (canForm(words[i], preWords)) {
130+
result.add(words[i]);
131+
}
132+
preWords.add(words[i]);
133+
}
134+
135+
return result;
136+
}
137+
138+
boolean canForm(String word, Set<String> dict) {
139+
if (dict.isEmpty()) {
140+
return false;
141+
}
142+
boolean[] dp = new boolean[word.length() + 1];
143+
dp[0] = true;
144+
for (int i = 1; i <= word.length(); i++) {
145+
for (int j = 0; j < i; j++) {
146+
if (dp[j] && dict.contains(word.substring(j, i))) {
147+
dp[i] = true;
148+
break;
149+
}
150+
}
151+
}
152+
return dp[word.length()];
153+
}
154+
}
178155
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy