648. Replace Words
In English, we have a concept called root, which can be followed by some other word to form another longer word - let’s call this word 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.
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 lower-case letters.
- 1 < = s e n t e n c e . l e n g t h < = 1 0 6 1 <= sentence.length <= 10^6 1<=sentence.length<=106
- sentence consists of only lower-case 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.
From: LeetCode
Link: 648. Replace Words
Solution:
Ideas:
1. Building the Trie:
- We insert each root word from the dictionary into the Trie, character by character.
- Mark the end of each root word.
2. Searching for the Shortest Root:
- For each word in the sentence, traverse the Trie.
- If a node with isEnd = 1 is found, return that prefix as the root.
3. Replacing Words in the Sentence:
- Tokenize the sentence using strsep().
- Check if a root exists for each word.
- Append the root or the original word to the output buffer.
Code:
#define MAX_WORD_LEN 100
#define MAX_SENTENCE_LEN 1000000
// Trie Node Structure
typedef struct TrieNode {
struct TrieNode* children[26];
int isEnd;
} TrieNode;
// Create a new Trie node
TrieNode* createTrieNode() {
TrieNode* node = (TrieNode*)malloc(sizeof(TrieNode));
node->isEnd = 0;
for (int i = 0; i < 26; i++) {
node->children[i] = NULL;
}
return node;
}
// Insert a word into the Trie
void insertTrie(TrieNode* root, char* word) {
TrieNode* node = root;
while (*word) {
int index = *word - 'a';
if (node->children[index] == NULL) {
node->children[index] = createTrieNode();
}
node = node->children[index];
word++;
}
node->isEnd = 1;
}
// Search for the shortest root in the Trie for a given word
char* searchRoot(TrieNode* root, char* word) {
TrieNode* node = root;
static char buffer[MAX_WORD_LEN + 1]; // Temporary buffer to store root
int len = 0;
while (*word) {
int index = *word - 'a';
if (node->children[index] == NULL) break; // No further root match
buffer[len++] = *word;
node = node->children[index];
if (node->isEnd) {
// Found the shortest root
buffer[len] = '\0';
return buffer;
}
word++;
}
return NULL; // No root found, return NULL
}
// Function to replace words in the sentence
char* replaceWords(char** dictionary, int dictionarySize, char* sentence) {
// Step 1: Build the Trie
TrieNode* root = createTrieNode();
for (int i = 0; i < dictionarySize; i++) {
insertTrie(root, dictionary[i]);
}
// Step 2: Process the sentence word by word
char* result = (char*)malloc(MAX_SENTENCE_LEN + 1);
char* word;
char* tempSentence = strdup(sentence); // Copy sentence to modify
char* ptr = tempSentence;
result[0] = '\0';
while ((word = strsep(&ptr, " ")) != NULL) {
if (*word == '\0') continue; // Skip empty tokens
char* rootWord = searchRoot(root, word);
if (rootWord) {
strcat(result, rootWord);
} else {
strcat(result, word);
}
if (ptr) strcat(result, " "); // Add space except for the last word
}
free(tempSentence);
return result;
}