力扣hot100 实现Trie(前缀树) 字典树 一题双解

Problem: 208. 实现 Trie (前缀树)

文章目录

  • 思路
  • 复杂度
  • [💝 TrieNode版](#💝 TrieNode版)
  • [💝 二维数组版](#💝 二维数组版)

思路

👩‍🏫 宫水三叶

复杂度

💝 TrieNode版

Java 复制代码
public class Trie
{
	class TrieNode
	{
		boolean end;//标记是否有以当前节点为结尾的字符串
		TrieNode[] ns = new TrieNode[26];
	}

	TrieNode root;

	public Trie()
	{
		root = new TrieNode();
	}

	public void insert(String word)
	{
		TrieNode p = root;
		for (int i = 0; i < word.length(); i++)
		{
			int u = word.charAt(i) - 'a';
//如果正在遍历的该字母在上一个节点的数组坐标中没有记录,就新建一个字母节点在字典树中
			if (p.ns[u] == null)//不存在此节点
				p.ns[u] = new TrieNode();//那就新建节点
			p = p.ns[u];//每一次生成字母都移动指针到下一个字母节点
		}
		p.end = true;// 以当前节点为结尾字符串的个数
	}

	public boolean search(String word)
	{
		TrieNode p = root;
		for (int i = 0; i < word.length(); i++)//枚举所有字符
		{
			int u = word.charAt(i) - 'a';
			if (p.ns[u] == null)//只要有一个字符不存在就 false
				return false;
			p = p.ns[u];
		}
		//最后还要看一下是否以当前字符串结尾
		//例:abcde 路径存在,查 abc,abc存在,但是没有以 c 为结尾的字符串,返回 false
		return p.end;
	}

	public boolean startsWith(String prefix)
	{
		TrieNode p = root;
		for (int i = 0; i < prefix.length(); i++)
		{
			int u = prefix.charAt(i) - 'a';
			if (p.ns[u] == null)
				return false;
			p = p.ns[u];
		}
		//所有字符存在即可,前缀即存在
		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);
 */

💝 二维数组版

复制代码
//数组版
public class Trie
{
	int N = 100010;
	int[][] trie;
	int[] cnt;
	int idx = 1;

	public Trie()
	{
//		int[i][j] 表示 第 i 行中的 ('a'+j) 是否存在(默认为 0 表示不存在)
		trie = new int[N][26];
		cnt = new int[N];// cnt[i] 记录 格子 i 被标记为结尾的次数
		idx = 1;// 给用到的格子进行编号(从 0 开始避开默认状态)
	}

	public void insert(String word)
	{
		int p = 0;
		for (int i = 0; i < word.length(); i++)
		{
			int u = word.charAt(i) - 'a';
			if (trie[p][u] == 0)
				trie[p][u] = ++idx;
			p = trie[p][u];
		}
		cnt[p]++;
	}

	public boolean search(String word)
	{
		int p = 0;
		for (int i = 0; i < word.length(); i++)
		{
			int u = word.charAt(i) - 'a';
			if (trie[p][u] == 0)
				return false;
			p = trie[p][u];
		}
		return cnt[p] != 0;

	}

	public boolean startsWith(String prefix)
	{
		int p = 0;
		for (int i = 0; i < prefix.length(); i++)
		{
			int u = prefix.charAt(i) - 'a';
			if (trie[p][u] == 0)
				return false;
			p = trie[p][u];
		}
		return true;
	}
}
相关推荐
Keep_Trying_Go43 分钟前
Consistent-Point半监督人群计数算法详解
人工智能·深度学习·算法·计算机视觉·人群计数
在所不辞兄1 小时前
【零基础学智能仿真-69】综合项目——材料参数驱动的仿真研究
人工智能·深度学习·神经网络·算法·机器学习·1024程序员节
Tisfy2 小时前
LeetCode 3665.统计镜子反射路径数目:三个动态规划数组
leetcode·动态规划·代理模式·题解
怕浪猫2 小时前
Super-agent 在各大模型厂商的应用情况
算法·面试·github
海绵宝宝转agent3 小时前
LeetCode100 二叉树个人题解
算法·leetcode·深度优先
octopus_c3 小时前
C++ 模板详解:函数模板、类模板、特化与分离编译
开发语言·c++·算法
東隅已逝,桑榆非晚3 小时前
算法1. 双指针法-移动零
c++·算法
CQU_JIAKE4 小时前
11.1[A]
算法
文丑颜不良啊4 小时前
LeetCode1581~1600题目解析
java·leetcode
椒颜皮皮虾྅4 小时前
让文档不止于文字:DeploySharp + PP-Structure,打通版面分析与表格重建
开发语言·学习·c#·.net·cuda