Skip to content

Commit 2155e1d

Browse files
authored
feat: add solutions for lc No.0648 (#5118)
1 parent 5692785 commit 2155e1d

File tree

10 files changed

+505
-577
lines changed

10 files changed

+505
-577
lines changed

solution/0600-0699/0648.Replace Words/README.md

Lines changed: 162 additions & 195 deletions
Large diffs are not rendered by default.

solution/0600-0699/0648.Replace Words/README_EN.md

Lines changed: 166 additions & 190 deletions
Large diffs are not rendered by default.
Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,50 @@
11
class Trie {
2-
private:
3-
Trie* children[26];
4-
int ref;
5-
62
public:
7-
Trie()
8-
: ref(-1) {
9-
memset(children, 0, sizeof(children));
10-
}
3+
Trie* children[26]{};
4+
bool isEnd = false;
115

12-
void insert(const string& w, int i) {
6+
void insert(const string& w) {
137
Trie* node = this;
14-
for (auto& c : w) {
8+
for (char c : w) {
159
int idx = c - 'a';
1610
if (!node->children[idx]) {
1711
node->children[idx] = new Trie();
1812
}
1913
node = node->children[idx];
2014
}
21-
node->ref = i;
15+
node->isEnd = true;
2216
}
2317

24-
int search(const string& w) {
18+
string search(const string& w) {
2519
Trie* node = this;
26-
for (auto& c : w) {
27-
int idx = c - 'a';
20+
for (int i = 0; i < w.size(); ++i) {
21+
int idx = w[i] - 'a';
2822
if (!node->children[idx]) {
29-
return -1;
23+
return w;
3024
}
3125
node = node->children[idx];
32-
if (node->ref != -1) {
33-
return node->ref;
26+
if (node->isEnd) {
27+
return w.substr(0, i + 1);
3428
}
3529
}
36-
return -1;
30+
return w;
3731
}
3832
};
3933

4034
class Solution {
4135
public:
4236
string replaceWords(vector<string>& dictionary, string sentence) {
43-
Trie* trie = new Trie();
44-
for (int i = 0; i < dictionary.size(); ++i) {
45-
trie->insert(dictionary[i], i);
37+
Trie trie;
38+
for (auto& w : dictionary) {
39+
trie.insert(w);
4640
}
41+
4742
stringstream ss(sentence);
48-
string w;
49-
string ans;
50-
while (ss >> w) {
51-
int idx = trie->search(w);
52-
ans += (idx == -1 ? w : dictionary[idx]) + " ";
43+
string word, res;
44+
while (ss >> word) {
45+
if (!res.empty()) res += " ";
46+
res += trie.search(word);
5347
}
54-
ans.pop_back();
55-
return ans;
48+
return res;
5649
}
57-
};
50+
};
Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,44 @@
11
type Trie struct {
22
children [26]*Trie
3-
ref int
3+
isEnd bool
44
}
55

6-
func newTrie() *Trie {
7-
return &Trie{ref: -1}
8-
}
9-
10-
func (this *Trie) insert(w string, i int) {
11-
node := this
6+
func (t *Trie) insert(w string) {
7+
node := t
128
for _, c := range w {
139
idx := c - 'a'
1410
if node.children[idx] == nil {
15-
node.children[idx] = newTrie()
11+
node.children[idx] = &Trie{}
1612
}
1713
node = node.children[idx]
1814
}
19-
node.ref = i
15+
node.isEnd = true
2016
}
2117

22-
func (this *Trie) search(w string) int {
23-
node := this
24-
for _, c := range w {
18+
func (t *Trie) search(w string) string {
19+
node := t
20+
for i, c := range w {
2521
idx := c - 'a'
2622
if node.children[idx] == nil {
27-
return -1
23+
return w
2824
}
2925
node = node.children[idx]
30-
if node.ref != -1 {
31-
return node.ref
26+
if node.isEnd {
27+
return w[:i+1]
3228
}
3329
}
34-
return -1
30+
return w
3531
}
3632

3733
func replaceWords(dictionary []string, sentence string) string {
38-
trie := newTrie()
39-
for i, w := range dictionary {
40-
trie.insert(w, i)
34+
trie := &Trie{}
35+
for _, w := range dictionary {
36+
trie.insert(w)
4137
}
42-
ans := strings.Builder{}
43-
for _, w := range strings.Split(sentence, " ") {
44-
if idx := trie.search(w); idx != -1 {
45-
ans.WriteString(dictionary[idx])
46-
} else {
47-
ans.WriteString(w)
48-
}
49-
ans.WriteByte(' ')
38+
39+
words := strings.Split(sentence, " ")
40+
for i, w := range words {
41+
words[i] = trie.search(w)
5042
}
51-
return ans.String()[:ans.Len()-1]
52-
}
43+
return strings.Join(words, " ")
44+
}
Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,46 @@
1+
class Trie {
2+
Trie[] children = new Trie[26];
3+
boolean isEnd = false;
4+
5+
void insert(String w) {
6+
Trie node = this;
7+
for (char c : w.toCharArray()) {
8+
int idx = c - 'a';
9+
if (node.children[idx] == null) {
10+
node.children[idx] = new Trie();
11+
}
12+
node = node.children[idx];
13+
}
14+
node.isEnd = true;
15+
}
16+
17+
String search(String w) {
18+
Trie node = this;
19+
for (int i = 0; i < w.length(); i++) {
20+
int idx = w.charAt(i) - 'a';
21+
if (node.children[idx] == null) {
22+
return w;
23+
}
24+
node = node.children[idx];
25+
if (node.isEnd) {
26+
return w.substring(0, i + 1);
27+
}
28+
}
29+
return w;
30+
}
31+
}
32+
133
class Solution {
234
public String replaceWords(List<String> dictionary, String sentence) {
3-
Set<String> s = new HashSet<>(dictionary);
35+
Trie trie = new Trie();
36+
for (String w : dictionary) {
37+
trie.insert(w);
38+
}
39+
440
String[] words = sentence.split(" ");
5-
for (int i = 0; i < words.length; ++i) {
6-
String word = words[i];
7-
for (int j = 1; j <= word.length(); ++j) {
8-
String t = word.substring(0, j);
9-
if (s.contains(t)) {
10-
words[i] = t;
11-
break;
12-
}
13-
}
41+
for (int i = 0; i < words.length; i++) {
42+
words[i] = trie.search(words[i]);
1443
}
1544
return String.join(" ", words);
1645
}
17-
}
46+
}
Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,32 @@
11
class Trie:
22
def __init__(self):
3-
self.children: List[Trie | None] = [None] * 26
4-
self.ref: int = -1
3+
self.children = [None] * 26
4+
self.is_end = False
55

6-
def insert(self, w: str, i: int):
6+
def insert(self, w: str) -> None:
77
node = self
88
for c in w:
99
idx = ord(c) - ord("a")
1010
if node.children[idx] is None:
1111
node.children[idx] = Trie()
1212
node = node.children[idx]
13-
node.ref = i
13+
node.is_end = True
1414

15-
def search(self, w: str) -> int:
15+
def search(self, w: str) -> str:
1616
node = self
17-
for c in w:
17+
for i, c in enumerate(w, 1):
1818
idx = ord(c) - ord("a")
1919
if node.children[idx] is None:
20-
return -1
20+
return w
2121
node = node.children[idx]
22-
if node.ref != -1:
23-
return node.ref
24-
return -1
22+
if node.is_end:
23+
return w[:i]
24+
return w
2525

2626

2727
class Solution:
2828
def replaceWords(self, dictionary: List[str], sentence: str) -> str:
2929
trie = Trie()
30-
for i, w in enumerate(dictionary):
31-
trie.insert(w, i)
32-
ans = []
33-
for w in sentence.split():
34-
idx = trie.search(w)
35-
ans.append(dictionary[idx] if idx != -1 else w)
36-
return " ".join(ans)
30+
for w in dictionary:
31+
trie.insert(w)
32+
return " ".join(trie.search(w) for w in sentence.split())
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
struct Trie {
2+
children: Vec<Option<Box<Trie>>>,
3+
is_end: bool,
4+
}
5+
6+
impl Trie {
7+
fn new() -> Self {
8+
Self {
9+
children: (0..26).map(|_| None).collect(),
10+
is_end: false,
11+
}
12+
}
13+
14+
fn insert(&mut self, w: String) {
15+
let mut node = self;
16+
for c in w.chars() {
17+
let idx = (c as u8 - b'a') as usize;
18+
node = node.children[idx].get_or_insert(Box::new(Trie::new()));
19+
}
20+
node.is_end = true;
21+
}
22+
23+
fn search(&self, w: &str) -> String {
24+
let mut node = self;
25+
for (i, c) in w.chars().enumerate() {
26+
let idx = (c as u8 - b'a') as usize;
27+
if node.children[idx].is_none() {
28+
return w.to_string();
29+
}
30+
node = node.children[idx].as_ref().unwrap();
31+
if node.is_end {
32+
return w[..i + 1].to_string();
33+
}
34+
}
35+
w.to_string()
36+
}
37+
}
38+
39+
impl Solution {
40+
pub fn replace_words(dictionary: Vec<String>, sentence: String) -> String {
41+
let mut trie = Trie::new();
42+
for w in dictionary {
43+
trie.insert(w);
44+
}
45+
46+
sentence
47+
.split_whitespace()
48+
.map(|w| trie.search(w))
49+
.collect::<Vec<_>>()
50+
.join(" ")
51+
}
52+
}
Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,48 @@
11
class Trie {
2-
#children: Record<string, Trie> = {};
3-
#ref = -1;
2+
children: Array<Trie | null>;
3+
isEnd: boolean;
44

5-
insert(w: string, i: number) {
5+
constructor() {
6+
this.children = new Array(26).fill(null);
7+
this.isEnd = false;
8+
}
9+
10+
insert(w: string): void {
611
let node: Trie = this;
712
for (const c of w) {
8-
node.#children[c] ??= new Trie();
9-
node = node.#children[c];
13+
const idx = c.charCodeAt(0) - 97;
14+
if (!node.children[idx]) {
15+
node.children[idx] = new Trie();
16+
}
17+
node = node.children[idx]!;
1018
}
11-
node.#ref = i;
19+
node.isEnd = true;
1220
}
1321

14-
search(w: string): number {
22+
search(w: string): string {
1523
let node: Trie = this;
16-
for (const c of w) {
17-
if (!node.#children[c]) {
18-
return -1;
24+
for (let i = 0; i < w.length; i++) {
25+
const idx = w.charCodeAt(i) - 97;
26+
if (!node.children[idx]) {
27+
return w;
1928
}
20-
node = node.#children[c];
21-
if (node.#ref !== -1) {
22-
return node.#ref;
29+
node = node.children[idx]!;
30+
if (node.isEnd) {
31+
return w.slice(0, i + 1);
2332
}
2433
}
25-
return -1;
34+
return w;
2635
}
2736
}
2837

2938
function replaceWords(dictionary: string[], sentence: string): string {
3039
const trie = new Trie();
31-
for (let i = 0; i < dictionary.length; i++) {
32-
trie.insert(dictionary[i], i);
40+
for (const w of dictionary) {
41+
trie.insert(w);
3342
}
43+
3444
return sentence
35-
.split(' ')
36-
.map(w => {
37-
const idx = trie.search(w);
38-
return idx !== -1 ? dictionary[idx] : w;
39-
})
40-
.join(' ');
45+
.split(" ")
46+
.map(w => trie.search(w))
47+
.join(" ");
4148
}

0 commit comments

Comments
 (0)