Replace Words
Problem Descriptionβ
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."
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.
Return the sentence after the replacement.
Examplesβ
Example 1:
Input: dictionary = ["cat","bat","rat"], sentence = "the cattle was rattled by the battery"
Output: "the cat was rat by the bat"
Example 2:
Input: dictionary = ["a","b","c"], sentence = "aadsfasf absbs bbab cadsfafs"
Output: "a a b c"
Constraintsβ
1 <= dictionary.length <= 1000
1 <= dictionary[i].length <= 100
dictionary[i]
consists of only lowercase letters.1 <= sentence.length <= 10^6
sentence
consists of only lowercase letters and spaces.- The number of words in
sentence
is in the range [1, 1000]. - The length of each word in
sentence
is in the range [1, 1000]. - Every two consecutive words in
sentence
will be separated by exactly one space. sentence
does not have leading or trailing spaces.
Solution for Replace Words Problemβ
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.
Approach: Trie Data Structureβ
-
Build the Trie:
- Insert all the roots from the dictionary into a Trie.
- 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.
-
Replace Derivatives:
- For each word in the sentence, traverse the Trie to find the shortest prefix (root).
- If found, replace the word with the root; otherwise, keep the word as is.
Code in Different Languagesβ
- C++
- Java
- Python
class TrieNode {
public:
unordered_map<char, TrieNode*> children;
string word = "";
};
class Trie {
public:
TrieNode* root;
Trie() {
root = new TrieNode();
}
void insert(string word) {
TrieNode* node = root;
for (char c : word) {
if (node->children.find(c) == node->children.end()) {
node->children[c] = new TrieNode();
}
node = node->children[c];
}
node->word = word;
}
string searchRoot(string word) {
TrieNode* node = root;
for (char c : word) {
if (node->children.find(c) == node->children.end()) {
return word;
}
node = node->children[c];
if (!node->word.empty()) {
return node->word;
}
}
return word;
}
};
class Solution {
public:
string replaceWords(vector<string>& dictionary, string sentence) {
Trie trie;
for (string root : dictionary) {
trie.insert(root);
}
stringstream ss(sentence);
string word;
string result;
while (ss >> word) {
if (!result.empty()) result += " ";
result += trie.searchRoot(word);
}
return result;
}
};
class TrieNode {
Map<Character, TrieNode> children = new HashMap<>();
String word = "";
}
class Trie {
TrieNode root;
public Trie() {
root = new TrieNode();
}
public void insert(String word) {
TrieNode node = root;
for (char c : word.toCharArray()) {
node.children.putIfAbsent(c, new TrieNode());
node = node.children.get(c);
}
node.word = word;
}
public String searchRoot(String word) {
TrieNode node = root;
for (char c : word.toCharArray()) {
if (!node.children.containsKey(c)) {
return word;
}
node = node.children.get(c);
if (!node.word.isEmpty()) {
return node.word;
}
}
return word;
}
}
class Solution {
public String replaceWords(List<String> dictionary, String sentence) {
Trie trie = new Trie();
for (String root : dictionary) {
trie.insert(root);
}
String[] words = sentence.split(" ");
StringBuilder result = new StringBuilder();
for (String word : words) {
if (result.length() > 0) {
result.append(" ");
}
result.append(trie.searchRoot(word));
}
return result.toString();
}
}
class TrieNode:
def __init__(self):
self.children = {}
self.word = ""
class Trie:
def __init__(self):
self.root = TrieNode()
def insert(self, word):
node = self.root
for char in word:
if char not in node.children:
node.children[char] = TrieNode()
node = node.children[char]
node.word = word
def searchRoot(self, word):
node = self.root
for char in word:
if char not in node.children:
return word
node = node.children[char]
if node.word:
return node.word
return word
class Solution:
def replaceWords(self, dictionary: List[str], sentence: str) -> str:
trie = Trie()
for root in dictionary:
trie.insert(root)
words = sentence.split()
for i in range(len(words)):
words[i] = trie.searchRoot(words[i])
return ' '.join(words)
Complexity Analysisβ
- Time Complexity: , where
N
is the total number of characters in the dictionary andL
is the length of the sentence. - Space Complexity: , where
N
is the total number of characters in the dictionary.