Skip to content

Commit dede018

Browse files
committed
added solution to 648
1 parent eae83d8 commit dede018

File tree

1 file changed

+262
-0
lines changed

1 file changed

+262
-0
lines changed
Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
---
2+
id: replace-words
3+
title: Replace Words
4+
sidebar_label: 648-Replace Words
5+
tags:
6+
- Trie
7+
- Hash Table
8+
- String Manipulation
9+
- LeetCode
10+
- Java
11+
- Python
12+
- C++
13+
description: "This is a solution to the Replace Words problem on LeetCode."
14+
sidebar_position: 3
15+
---
16+
17+
## Problem Description
18+
19+
In English, we have a concept called a root, which can be followed by some other word to form another longer word - let's call this word a derivative. For example, when the root "help" is followed by the word "ful," we can form a derivative "helpful."
20+
21+
Given a dictionary consisting of many roots and a sentence consisting of words separated by spaces, replace all the derivatives in the sentence with the root forming it. If a derivative can be replaced by more than one root, replace it with the root that has the shortest length.
22+
23+
Return the sentence after the replacement.
24+
25+
### Examples
26+
27+
**Example 1:**
28+
29+
```
30+
Input: dictionary = ["cat","bat","rat"], sentence = "the cattle was rattled by the battery"
31+
Output: "the cat was rat by the bat"
32+
```
33+
34+
**Example 2:**
35+
36+
```
37+
Input: dictionary = ["a","b","c"], sentence = "aadsfasf absbs bbab cadsfafs"
38+
Output: "a a b c"
39+
```
40+
41+
### Constraints
42+
43+
- `1 <= dictionary.length <= 1000`
44+
- `1 <= dictionary[i].length <= 100`
45+
- `dictionary[i]` consists of only lowercase letters.
46+
- `1 <= sentence.length <= 10^6`
47+
- `sentence` consists of only lowercase letters and spaces.
48+
- The number of words in `sentence` is in the range [1, 1000].
49+
- The length of each word in `sentence` is in the range [1, 1000].
50+
- Every two consecutive words in `sentence` will be separated by exactly one space.
51+
- `sentence` does not have leading or trailing spaces.
52+
53+
---
54+
55+
## Solution for Replace Words Problem
56+
57+
To solve this problem, we need to efficiently replace the derivatives in the sentence with their respective roots from the dictionary. We can approach this problem using a Trie data structure for efficient prefix matching.
58+
59+
### Approach: Trie Data Structure
60+
61+
1. **Build the Trie:**
62+
- Insert all the roots from the dictionary into a Trie.
63+
- Each node in the Trie represents a character, and the path from the root to any node represents a prefix of one or more roots.
64+
65+
2. **Replace Derivatives:**
66+
- For each word in the sentence, traverse the Trie to find the shortest prefix (root).
67+
- If found, replace the word with the root; otherwise, keep the word as is.
68+
69+
### Code in Different Languages
70+
71+
<Tabs>
72+
<TabItem value="C++" label="C++" default>
73+
<SolutionAuthor name="@ImmidiSivani"/>
74+
75+
```cpp
76+
class TrieNode {
77+
public:
78+
unordered_map<char, TrieNode*> children;
79+
string word = "";
80+
};
81+
82+
class Trie {
83+
public:
84+
TrieNode* root;
85+
86+
Trie() {
87+
root = new TrieNode();
88+
}
89+
90+
void insert(string word) {
91+
TrieNode* node = root;
92+
for (char c : word) {
93+
if (node->children.find(c) == node->children.end()) {
94+
node->children[c] = new TrieNode();
95+
}
96+
node = node->children[c];
97+
}
98+
node->word = word;
99+
}
100+
101+
string searchRoot(string word) {
102+
TrieNode* node = root;
103+
for (char c : word) {
104+
if (node->children.find(c) == node->children.end()) {
105+
return word;
106+
}
107+
node = node->children[c];
108+
if (!node->word.empty()) {
109+
return node->word;
110+
}
111+
}
112+
return word;
113+
}
114+
};
115+
116+
class Solution {
117+
public:
118+
string replaceWords(vector<string>& dictionary, string sentence) {
119+
Trie trie;
120+
for (string root : dictionary) {
121+
trie.insert(root);
122+
}
123+
124+
stringstream ss(sentence);
125+
string word;
126+
string result;
127+
128+
while (ss >> word) {
129+
if (!result.empty()) result += " ";
130+
result += trie.searchRoot(word);
131+
}
132+
133+
return result;
134+
}
135+
};
136+
```
137+
138+
</TabItem>
139+
<TabItem value="Java" label="Java">
140+
<SolutionAuthor name="@ImmidiSivani"/>
141+
142+
```java
143+
class TrieNode {
144+
Map<Character, TrieNode> children = new HashMap<>();
145+
String word = "";
146+
}
147+
148+
class Trie {
149+
TrieNode root;
150+
151+
public Trie() {
152+
root = new TrieNode();
153+
}
154+
155+
public void insert(String word) {
156+
TrieNode node = root;
157+
for (char c : word.toCharArray()) {
158+
node.children.putIfAbsent(c, new TrieNode());
159+
node = node.children.get(c);
160+
}
161+
node.word = word;
162+
}
163+
164+
public String searchRoot(String word) {
165+
TrieNode node = root;
166+
for (char c : word.toCharArray()) {
167+
if (!node.children.containsKey(c)) {
168+
return word;
169+
}
170+
node = node.children.get(c);
171+
if (!node.word.isEmpty()) {
172+
return node.word;
173+
}
174+
}
175+
return word;
176+
}
177+
}
178+
179+
class Solution {
180+
public String replaceWords(List<String> dictionary, String sentence) {
181+
Trie trie = new Trie();
182+
for (String root : dictionary) {
183+
trie.insert(root);
184+
}
185+
186+
String[] words = sentence.split(" ");
187+
StringBuilder result = new StringBuilder();
188+
189+
for (String word : words) {
190+
if (result.length() > 0) {
191+
result.append(" ");
192+
}
193+
result.append(trie.searchRoot(word));
194+
}
195+
196+
return result.toString();
197+
}
198+
}
199+
```
200+
201+
</TabItem>
202+
<TabItem value="Python" label="Python">
203+
<SolutionAuthor name="@ImmidiSivani"/>
204+
205+
```python
206+
class TrieNode:
207+
def __init__(self):
208+
self.children = {}
209+
self.word = ""
210+
211+
class Trie:
212+
def __init__(self):
213+
self.root = TrieNode()
214+
215+
def insert(self, word):
216+
node = self.root
217+
for char in word:
218+
if char not in node.children:
219+
node.children[char] = TrieNode()
220+
node = node.children[char]
221+
node.word = word
222+
223+
def searchRoot(self, word):
224+
node = self.root
225+
for char in word:
226+
if char not in node.children:
227+
return word
228+
node = node.children[char]
229+
if node.word:
230+
return node.word
231+
return word
232+
233+
class Solution:
234+
def replaceWords(self, dictionary: List[str], sentence: str) -> str:
235+
trie = Trie()
236+
for root in dictionary:
237+
trie.insert(root)
238+
239+
words = sentence.split()
240+
for i in range(len(words)):
241+
words[i] = trie.searchRoot(words[i])
242+
243+
return ' '.join(words)
244+
```
245+
246+
</TabItem>
247+
</Tabs>
248+
249+
#### Complexity Analysis
250+
251+
- **Time Complexity**: $O(N + L)$, where `N` is the total number of characters in the dictionary and `L` is the length of the sentence.
252+
- **Space Complexity**: $O(N)$, where `N` is the total number of characters in the dictionary.
253+
254+
---
255+
256+
<h2>Authors:</h2>
257+
258+
<div style={{display: 'flex', flexWrap: 'wrap', justifyContent: 'space-between', gap: '10px'}}>
259+
{['ImmidiSivani'].map(username => (
260+
<Author key={username} username={username} />
261+
))}
262+
</div>

0 commit comments

Comments
 (0)