- 3.1
- 这里是以数组下标是否为 null 来看有没有链表的下个字母
| 类名 | 构造函数 | 为什么这么写? |
|---|---|---|
DLinkedList | 重载了两个 | 既要创建“什么都不存”的哨兵节点,又要创建“存了数据”的业务节点。 |
TrieNode | 只需要一个 | 每个节点出生时都必须把那 26 个槽位准备好,且大家出生时都是“干净”的,没有差异化需求。 |
class TrieNode{
boolean flag;
TrieNode[] node;
public TrieNode(){
node = new TrieNode[26];
flag = false;
}
}
class Trie {
TrieNode root;
public Trie() {
root = new TrieNode();
}
public void insert(String word) {
TrieNode cur = root;
for(int i=0;i<word.length();i++){
char ch = word.charAt(i);
if(cur.node[ch-'a']==null){
cur.node[ch-'a'] = new TrieNode();
}
cur = cur.node[ch-'a'];
}
cur.flag = true;
}
public boolean search(String word) {
TrieNode cur = root;
for(int i=0;i<word.length();i++){
char ch = word.charAt(i);
if(cur.node[ch-'a']==null){
return false;
}
cur = cur.node[ch-'a'];
}
return cur.flag;
}
public boolean startsWith(String prefix) {
TrieNode cur = root;
for(int i=0;i<prefix.length();i++){
char ch = prefix.charAt(i);
if(cur.node[ch-'a']==null){
return false;
}
cur = cur.node[ch-'a'];
}
return true;
}
}
-
1.30
-
需要在外面定义TrieNode 节点,包含标志位与 next = TrieNode【26】
- Trie 的构造函数,里 new TrieNode 为 root
- 在三个函数中,判断用 node 传承 root,开始遍历当前是否存在后续,如果不存在,创建?返回错误?
- search 与 prefix 只有一个区别是是否返回标志位
-
11.15
- 首先这其实跟图论美鸡毛关系(但其实有点像邻接矩阵),更像多叉树:26叉树,用数组TrieNode[] children;表示
- 类似于链表或二叉树,的val值,这里也有一个isEnd的标记
class TreeNode {
int val;
TreeNode left;
TreeNode right;
}
class ListNode {
int val;
ListNode next;
}
class TrieNode {
TrieNode[] children;
}- 在Trei类下,先声明全局根节点root
- 在写构造函数(不需要返回值),自动执行root = new TrieNode();
- 最后就是三个函数,其实就是二叉树往下走,但更像链表node = node.next,node.next = new ListNode();
- 注意String word 的逐字母遍历!和idx的定位。x-‘a’
class Trie {
public Trie() {
}
public void insert(String word) {
}
public boolean search(String word) {
}
public boolean startsWith(String prefix) {
}
}class TrieNode{
TrieNode[] children;
boolean isEnd;
public TrieNode(){
children = new TrieNode[26];// 26 个字母的子节点
isEnd = false;// 是否是一个完整单词的结尾
}
}
class Trie {
private TrieNode root;
public Trie() {
root = new TrieNode();
}
public void insert(String word) {
TrieNode node = root;
for(char c:word.toCharArray()){
int idx = c-'a';
if(node.children[idx]==null){
node.children[idx]=new TrieNode();
}
node = node.children[idx];
}
node.isEnd = true;
}
public boolean search(String word) {
TrieNode node = root;
for(char c:word.toCharArray()){
int idx = c-'a';
if(node.children[idx]==null) return false;
node = node.children[idx];
}
return node.isEnd;
}
public boolean startsWith(String prefix) {
TrieNode node = root;
for(char c:prefix.toCharArray()){
int idx = c-'a';
if(node.children[idx]==null) return false;
node = node.children[idx];
}
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);
*/Trie ├── insert() → 构建路径 + 标记结尾 ├── search() → 走完整路径 + 检查 isEnd └── startsWith() → 走完整路径即可
Trie(发音 “try”)又叫字典树 / 前缀树, 它是一种专门用于字符串检索的树形结构。 它能高效地解决这些问题:
- 插入一个单词
- 判断一个单词是否存在
- 判断是否有某个前缀存在
📘 核心思想
Trie 的每个节点代表一个字符, 从根节点到某个节点的路径,表示一个字符串的前缀。