Skip to content

Commit dcc9c2e

Browse files
committed
leetcode
1 parent f81d389 commit dcc9c2e

File tree

4 files changed

+268
-0
lines changed

4 files changed

+268
-0
lines changed
+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
3+
4+
5+
-* 472. Concatenated Words *-
6+
7+
Given an array of strings words (without duplicates), return all the concatenated words in the given list of words.
8+
9+
A concatenated word is defined as a string that is comprised entirely of at least two shorter words in the given array.
10+
11+
12+
13+
Example 1:
14+
15+
Input: words = ["cat","cats","catsdogcats","dog","dogcatsdog","hippopotamuses","rat","ratcatdogcat"]
16+
Output: ["catsdogcats","dogcatsdog","ratcatdogcat"]
17+
Explanation: "catsdogcats" can be concatenated by "cats", "dog" and "cats";
18+
"dogcatsdog" can be concatenated by "dog", "cats" and "dog";
19+
"ratcatdogcat" can be concatenated by "rat", "cat", "dog" and "cat".
20+
Example 2:
21+
22+
Input: words = ["cat","dog","catdog"]
23+
Output: ["catdog"]
24+
25+
26+
Constraints:
27+
28+
1 <= words.length <= 104
29+
1 <= words[i].length <= 30
30+
words[i] consists of only lowercase English letters.
31+
All the strings of words are unique.
32+
1 <= sum(words[i].length) <= 105
33+
34+
35+
36+
37+
38+
*/
39+
40+
import 'dart:collection';
41+
42+
class A {
43+
bool checkConcatenate(String word, Set<String> s) {
44+
for (int i = 1; i < word.length; i++) {
45+
String prefixWord = word.substring(0, i);
46+
String suffixWord = word.substring(i, word.length);
47+
if (s.contains(prefixWord) &&
48+
(s.contains(suffixWord) || checkConcatenate(suffixWord, s)))
49+
return true;
50+
}
51+
return false;
52+
}
53+
54+
List<String> findAllConcatenatedWordsInADict(List<String> words) {
55+
HashSet<String> s = HashSet();
56+
List<String> concatenateWords = [];
57+
for (String word in words) s.add(word);
58+
for (String word in words) {
59+
if (checkConcatenate(word, s) == true) concatenateWords.add(word);
60+
}
61+
return concatenateWords;
62+
}
63+
}
64+
65+
class B {
66+
List<String> findAllConcatenatedWordsInADict(List<String> words) {
67+
HashSet<String> wordsSet = HashSet();
68+
for (String word in words) wordsSet.add(word);
69+
List<String> res = [];
70+
71+
for (String word in words) {
72+
int n = word.length;
73+
List<int> dp = List.filled(n + 1, 0);
74+
dp[0] = 1;
75+
for (int i = 0; i < n; i++) {
76+
if (dp[i] != 0) continue;
77+
for (int j = i + 1; j <= n; j++) {
78+
if (j - i < n && wordsSet.contains(word.substring(i, j - i))) {
79+
dp[j] = 1;
80+
}
81+
}
82+
if (dp[n] == 0) {
83+
res.add(word);
84+
break;
85+
}
86+
}
87+
}
88+
return res;
89+
}
90+
}
91+
92+
class C {
93+
List<String> findAllConcatenatedWordsInADict(List<String> words) {
94+
List<String> result = [];
95+
HashSet<String> set = HashSet();
96+
for (String word in words) set.add(word);
97+
for (String word in words) helper(result, set, word);
98+
return result;
99+
}
100+
101+
void helper(List<String> list, HashSet<String> set, String word) {
102+
if (word.length == 0) return;
103+
List<bool> dp = List.filled(word.length + 1, false);
104+
dp[0] = true;
105+
for (int i = 0; i < word.length; i++) {
106+
if (!dp[i]) continue;
107+
for (int j = i + 1; j < dp.length; j++) {
108+
if (i == 0 && j == word.length) continue;
109+
if (set.contains(word.substring(i, j))) dp[j] = true;
110+
}
111+
}
112+
if (dp[dp.length - 1]) list.add(word);
113+
}
114+
}
+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package main
2+
3+
type Trie struct {
4+
Children map[string]*Trie // important to make it a pointer to modify the Children.Trie value
5+
End bool
6+
}
7+
8+
func NewTrie() *Trie {
9+
return &Trie{
10+
Children: make(map[string]*Trie),
11+
End: false,
12+
}
13+
}
14+
15+
func addWord(t *Trie, word string) {
16+
var current *Trie = t
17+
for i := 0; i < len(word); i++ {
18+
letter := string(word[i])
19+
if _, ok := current.Children[letter]; !ok {
20+
current.Children[letter] = NewTrie()
21+
}
22+
current = current.Children[letter]
23+
}
24+
current.End = true
25+
}
26+
27+
func searchConcat(root *Trie, word string, index int, count int) bool {
28+
// base case
29+
if index >= len(word) {
30+
return count >= 2
31+
}
32+
33+
var current *Trie = root
34+
35+
for i := index; i < len(word); i++ {
36+
letter := string(word[i])
37+
if _, ok := current.Children[letter]; !ok {
38+
break
39+
}
40+
41+
current = current.Children[letter]
42+
43+
// when we reach the end, 2 choices
44+
// restart or continue
45+
if current.End {
46+
47+
// restart
48+
atRestart := searchConcat(root, word, i+1, count+1)
49+
if atRestart {
50+
return true
51+
} else {
52+
// continue down the branch
53+
continue
54+
}
55+
}
56+
}
57+
return false
58+
}
59+
60+
func findAllConcatenatedWordsInADict(words []string) []string {
61+
var trie *Trie = NewTrie()
62+
for _, word := range words {
63+
addWord(trie, word)
64+
}
65+
66+
var validWords []string = []string{}
67+
for _, word := range words {
68+
isFound := searchConcat(trie, word, 0, 0)
69+
if isFound {
70+
validWords = append(validWords, word)
71+
}
72+
}
73+
return validWords
74+
}
+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# 🔥 2 Approaches 🔥 || Simple Fast and Easy || with Explanation
2+
3+
## Solution - Recursion - Depth First Search
4+
5+
### Approach for this Problem
6+
7+
Create an empty set 's' to store all the words in the given array of strings.
8+
Iterate through the array of strings and insert each word into the set 's'.
9+
Create an empty vector 'concatenateWords' to store all the concatenated words.
10+
Iterate through the array of strings again, for each word, check if it is a concatenated word using the function 'checkConcatenate(word)'.
11+
In the 'checkConcatenate(word)' function, use a for loop to iterate through each substring of the word, starting from index 1 to the second last index of the word.
12+
For each substring, check if the prefix and suffix of the substring exists in the set 's'.
13+
If the prefix and suffix both exist in the set 's', then return true, indicating that the word is a concatenated word.
14+
If the function 'checkConcatenate(word)' returns true, then insert the word into the 'concatenateWords' vector.
15+
Return the 'concatenateWords' vector.
16+
17+
### Time Complexity and Space Complexity
18+
19+
- Time complexity: O(n^2*m) //where n is the number of words in the input array and m is the average length of the words.
20+
- Space complexity: O(n*m) //where n is the number of words in the input array and m is the average length of the words.
21+
22+
### Code
23+
24+
```dart
25+
import 'dart:collection';
26+
27+
class Solution {
28+
bool checkConcatenate(String word, Set<String> s) {
29+
for (int i = 1; i < word.length; i++) {
30+
String prefixWord = word.substring(0, i);
31+
String suffixWord = word.substring(i, word.length);
32+
if (s.contains(prefixWord) &&
33+
(s.contains(suffixWord) || checkConcatenate(suffixWord, s)))
34+
return true;
35+
}
36+
return false;
37+
}
38+
39+
List<String> findAllConcatenatedWordsInADict(List<String> words) {
40+
HashSet<String> s = HashSet();
41+
List<String> concatenateWords = [];
42+
for (String word in words) s.add(word);
43+
for (String word in words) {
44+
if (checkConcatenate(word, s) == true) concatenateWords.add(word);
45+
}
46+
return concatenateWords;
47+
}
48+
}
49+
```
50+
51+
## Solution - 2 DP
52+
53+
### Code
54+
55+
```dart
56+
class Solution {
57+
List<String> findAllConcatenatedWordsInADict(List<String> words) {
58+
List<String> result = [];
59+
HashSet<String> set = HashSet();
60+
for (String word in words) set.add(word);
61+
for (String word in words) helper(result, set, word);
62+
return result;
63+
}
64+
65+
void helper(List<String> list, HashSet<String> set, String word) {
66+
if (word.length == 0) return;
67+
List<bool> dp = List.filled(word.length + 1, false);
68+
dp[0] = true;
69+
for (int i = 0; i < word.length; i++) {
70+
if (!dp[i]) continue;
71+
for (int j = i + 1; j < dp.length; j++) {
72+
if (i == 0 && j == word.length) continue;
73+
if (set.contains(word.substring(i, j))) dp[j] = true;
74+
}
75+
}
76+
if (dp[dp.length - 1]) list.add(word);
77+
}
78+
}
79+
```

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ This repo contain leetcode solution using DART and GO programming language. Most
195195
- [**909.** Snakes and Ladders](SnakesAndLadders/snakes_and_ladders.dart)
196196
- [**2359.** Find Closest Node to Given Two Nodes](FindClosestNodeToGivenTwoNodes/find_closest_node_to_given_two_nodes.dart)
197197
- [**787.** Cheapest Flights Within K Stops](CheapestFlightsWithinKStops/cheapest_flights_within_k_stops.dart)
198+
- [**472.** Concatenated Words](ConcatenatedWords/concatenated_words.dart)
198199

199200
## Reach me via
200201

0 commit comments

Comments
 (0)