Welcome to Subscribe On Youtube
648. Replace Words
Description
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 successor. For example, when the root "an"
is followed by the successor word "other"
, we can form a new word "another"
.
Given a dictionary
consisting of many roots and a sentence
consisting of words separated by spaces, replace all the successors in the sentence with the root forming it. If a successor 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 <= 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.
Solutions
-
class Trie { private Trie[] children = new Trie[26]; private int ref = -1; public void insert(String w, int i) { Trie node = this; for (int j = 0; j < w.length(); ++j) { int idx = w.charAt(j) - 'a'; if (node.children[idx] == null) { node.children[idx] = new Trie(); } node = node.children[idx]; } node.ref = i; } public int search(String w) { Trie node = this; for (int j = 0; j < w.length(); ++j) { int idx = w.charAt(j) - 'a'; if (node.children[idx] == null) { return -1; } node = node.children[idx]; if (node.ref != -1) { return node.ref; } } return -1; } } class Solution { public String replaceWords(List<String> dictionary, String sentence) { Trie trie = new Trie(); for (int i = 0; i < dictionary.size(); ++i) { trie.insert(dictionary.get(i), i); } List<String> ans = new ArrayList<>(); for (String w : sentence.split("\\s")) { int idx = trie.search(w); ans.add(idx == -1 ? w : dictionary.get(idx)); } return String.join(" ", ans); } }
-
class Trie { private: Trie* children[26]; int ref; public: Trie() : ref(-1) { memset(children, 0, sizeof(children)); } void insert(const string& w, int i) { Trie* node = this; for (auto& c : w) { int idx = c - 'a'; if (!node->children[idx]) { node->children[idx] = new Trie(); } node = node->children[idx]; } node->ref = i; } int search(const string& w) { Trie* node = this; for (auto& c : w) { int idx = c - 'a'; if (!node->children[idx]) { return -1; } node = node->children[idx]; if (node->ref != -1) { return node->ref; } } return -1; } }; class Solution { public: string replaceWords(vector<string>& dictionary, string sentence) { Trie* trie = new Trie(); for (int i = 0; i < dictionary.size(); ++i) { trie->insert(dictionary[i], i); } stringstream ss(sentence); string w; string ans; while (ss >> w) { int idx = trie->search(w); ans += (idx == -1 ? w : dictionary[idx]) + " "; } ans.pop_back(); return ans; } };
-
class Trie: def __init__(self): self.children: List[Trie | None] = [None] * 26 self.ref: int = -1 def insert(self, w: str, i: int): node = self for c in w: idx = ord(c) - ord("a") if node.children[idx] is None: node.children[idx] = Trie() node = node.children[idx] node.ref = i def search(self, w: str) -> int: node = self for c in w: idx = ord(c) - ord("a") if node.children[idx] is None: return -1 node = node.children[idx] if node.ref != -1: return node.ref return -1 class Solution: def replaceWords(self, dictionary: List[str], sentence: str) -> str: trie = Trie() for i, w in enumerate(dictionary): trie.insert(w, i) ans = [] for w in sentence.split(): idx = trie.search(w) ans.append(dictionary[idx] if idx != -1 else w) return " ".join(ans)
-
type Trie struct { children [26]*Trie ref int } func newTrie() *Trie { return &Trie{ref: -1} } func (this *Trie) insert(w string, i int) { node := this for _, c := range w { idx := c - 'a' if node.children[idx] == nil { node.children[idx] = newTrie() } node = node.children[idx] } node.ref = i } func (this *Trie) search(w string) int { node := this for _, c := range w { idx := c - 'a' if node.children[idx] == nil { return -1 } node = node.children[idx] if node.ref != -1 { return node.ref } } return -1 } func replaceWords(dictionary []string, sentence string) string { trie := newTrie() for i, w := range dictionary { trie.insert(w, i) } ans := strings.Builder{} for _, w := range strings.Split(sentence, " ") { if idx := trie.search(w); idx != -1 { ans.WriteString(dictionary[idx]) } else { ans.WriteString(w) } ans.WriteByte(' ') } return ans.String()[:ans.Len()-1] }
-
class Trie { private children: Trie[]; private ref: number; constructor() { this.children = new Array<Trie>(26); this.ref = -1; } public insert(w: string, i: number) { let node: Trie = this; for (const c of w) { const idx = c.charCodeAt(0) - 97; if (!node.children[idx]) { node.children[idx] = new Trie(); } node = node.children[idx]; } node.ref = i; } public search(w: string): number { let node: Trie = this; for (const c of w) { const idx = c.charCodeAt(0) - 97; if (!node.children[idx]) { return -1; } node = node.children[idx]; if (node.ref !== -1) { return node.ref; } } return -1; } } function replaceWords(dictionary: string[], sentence: string): string { const trie = new Trie(); for (let i = 0; i < dictionary.length; i++) { trie.insert(dictionary[i], i); } return sentence .split(' ') .map(w => { const idx = trie.search(w); return idx !== -1 ? dictionary[idx] : w; }) .join(' '); }