Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+144-167
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)