Trie

前缀树主要用于解决与字符串查找相关d

剑指 Offer II 062. 实现前缀树

方法一:前缀树

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
class Trie {
static class TrieNode {
private TrieNode[] children = new TrieNode[26];
private boolean isWord;
}
/** Initialize your data structure here. */
private TrieNode root = new TrieNode();

/** Inserts a word into the trie. */
public void insert(String word) {
TrieNode node = root;
for (char ch : word.toCharArray()) {
if (node.children[ch - 'a'] == null)
node.children[ch - 'a'] = new TrieNode();
node = node.children[ch - 'a'];
}
node.isWord = true;
}

/** Returns if the word is in the trie. */
public boolean search(String word) {
TrieNode node = root;
for (char ch : word.toCharArray()) {
if (node.children[ch - 'a'] == null)
return false;
node = node.children[ch - 'a'];
}
return node.isWord;
}

/** Returns if there is any word in the trie that starts with the given prefix. */
public boolean startsWith(String prefix) {
TrieNode node = root;
for (char ch : prefix.toCharArray()) {
if (node.children[ch - 'a'] == null)
return false;
node = node.children[ch - 'a'];
}
return true;
}
}

/**
* Your Trie object will be instantiated and called as such:
* Trie obj = new Trie();
* obj.insert(word);
* boolean param_2 = obj.search(word);
* boolean param_3 = obj.startsWith(prefix);
*/

剑指 Offer II 063. 替换单词

一刷:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
class Solution {
static class TrieNode {
private TrieNode[] children;
private boolean isWord;
public TrieNode() {
children = new TrieNode[26];
}
}


public String replaceWords(List<String> dictionary, String sentence) {
TrieNode root = buildTrie(dictionary);
String[] words = sentence.split(" ");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < words.length; ++i) {
String prefix = findPrefix(root, words[i]);
if (!prefix.isEmpty()) {
words[i] = prefix;
}
}
return String.join(" ", words);
}

private String findPrefix(TrieNode root, String word) {
TrieNode cur = root;
StringBuilder sb = new StringBuilder();
for (char ch : word.toCharArray()) {
if (cur.children[ch - 'a'] == null || cur.isWord)
break;
sb.append(ch);
cur = cur.children[ch - 'a'];
}
return cur.isWord == true ? sb.toString() : "";
}

private TrieNode buildTrie(List<String> dictionary) {
TrieNode root = new TrieNode();
for (String str : dictionary) {
TrieNode cur = root;
for (char ch : str.toCharArray()) {
if (cur.children[ch - 'a'] == null)
cur.children[ch - 'a'] = new TrieNode();
cur = cur.children[ch - 'a'];
}
cur.isWord = true;
}
return root;
}
}

二刷

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class Solution {
static class TrieNode {
TrieNode[] children = new TrieNode[26];
boolean isWord;
}
TrieNode root = new TrieNode();
private void buildDict(List<String> dictionary) {
for (String word : dictionary) {
TrieNode node = root;
for (char ch : word.toCharArray()) {
if (node.children[ch - 'a'] == null)
node.children[ch - 'a'] = new TrieNode();
node = node.children[ch - 'a'];
}
node.isWord = true;
}
}

public String replaceWords(List<String> dictionary, String sentence) {
buildDict(dictionary);
String[] words = sentence.split(" ");
StringBuilder res = new StringBuilder(), sb = new StringBuilder();
for (String word : words) {
TrieNode node = root;
for (char ch : word.toCharArray()) {
if (node.children[ch - 'a'] == null)
break;
sb.append(ch);
node = node.children[ch - 'a'];
if (node.isWord) {
sb.append(" ");
res.append(sb);
sb = new StringBuilder();
break;
}
}
sb = new StringBuilder();
if (!node.isWord)
res.append(word + " ");
}
res.deleteCharAt(res.length() - 1);
return res.toString();
}
}

剑指 Offer II 064. 神奇的字典

方法一:前缀树

注意:一定要判断root.isWord,比如字典里有“hello”,search(“hhll”)

1
2
if (root.isWord && index == searchWord.length() && diff == 1)
return true;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
class MagicDictionary {

static class TrieNode {
TrieNode[] children = new TrieNode[26];
boolean isWord;
}
/** Initialize your data structure here. */
TrieNode root = new TrieNode();

public void buildDict(String[] dictionary) {
for (String word : dictionary) {
TrieNode node = root;
for (char ch : word.toCharArray()) {
if (node.children[ch - 'a'] == null)
node.children[ch - 'a'] = new TrieNode();
node = node.children[ch - 'a'];
}
node.isWord = true;
}
}

public boolean search(String searchWord) {
return dfs(root, searchWord, 0, 0);
}

private boolean dfs(TrieNode root, String searchWord, int index, int diff) {
if (root == null || diff > 1)
return false;
if (root.isWord && index == searchWord.length() && diff == 1)
return true;
if (index == searchWord.length())
return false;
boolean found = false;
for (int i = 0; i < 26; ++i) {
if (found)
break;
int nextDiff = i == searchWord.charAt(index) - 'a' ? diff : diff + 1;
found = dfs(root.children[i], searchWord, index + 1, nextDiff);
}
return found;
}
}
/**
* Your MagicDictionary object will be instantiated and called as such:
* MagicDictionary obj = new MagicDictionary();
* obj.buildDict(dictionary);
* boolean param_2 = obj.search(searchWord);
*/

Trie
https://leopol1d.github.io/2023/06/06/trie/
作者
Leopold
发布于
2023年6月6日
许可协议