LeetCode 单词搜索II(回溯法+前缀树)

该博客探讨如何在二维网格中寻找字典中的单词,采用回溯法结合前缀树数据结构来优化搜索效率。首先介绍问题背景和回溯法的基本思路,然后讲解前缀树的原理,并引用了相关LeetCode题目来进一步解释前缀树的构建和使用。最后,阐述如何结合这两种方法解决大规模数据测试时的单词搜索问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

给定一个二维网格 board 和一个字典中的单词列表 words,找出所有同时在二维网格和字典中出现的单词。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母在一个单词中不允许被重复使用。

示例:

输入: 
words = ["oath","pea","eat","rain"] and board =
[
  ['o','a','a','n'],
  ['e','t','a','e'],
  ['i','h','k','r'],
  ['i','f','l','v']
]
输出: ["eat","oath"]

说明:
你可以假设所有输入都由小写字母 a-z 组成。

提示:

你需要优化回溯算法以通过更大数据量的测试。你能否早点停止回溯?
如果当前单词不存在于所有单词的前缀中,则可以立即停止回溯。什么样的数据结构可以有效地执行这样的操作?散列表是否可行?为什么? 
前缀树如何?如果你想学习如何实现一个基本的前缀树,请先查看这个问题: 实现Trie(前缀树)。

请先翻阅 LeetCode 单词搜索(图解)
这道题与上一题基本一样,还是使用回溯法但是这道题的数据测试量非常大。
而搜索单词,当单词量时,会存在大量的公共前缀。比如存在单词“aabcd”,“aacad”,在进行搜索时,公共前缀“aa”需要重复搜索。那么有没有一种结构能将它们的公共前缀合并,从而减少搜索次数呢?
答案是显然的,这时就要利用鼎鼎大名**“前缀树”**数据结构来解决重复的问题。

请先翻阅 LeetCode 实现Trie(前缀树)
上面的博客讲解了如何构造一个前缀树。

请先翻阅 LeetCode 添加与搜索单词(基于前缀树)
上面的博客讲解了如何利用前缀树来储存单词。

请先认真阅读上面的博客,下面的代码实现都是基于上面的铺垫。
在此题,我们想将所有的word构建一个前缀树,然后从字符矩阵中进行回溯法搜索。LeetCode 单词搜索(图解)

//前缀树的程序表示
class TrieNode {
   
public:
	bool isWord;//当前节点为结尾是否是字符串
	vector<TrieNode*> children;
	TrieNode() : isWord(false), children(26, nullptr) {
   }
	~TrieNode() {
   
		for (TrieNode* child : children)
			if (child) delete child;
	}
};
class Solution {
   
private:
	TrieNode * trieRoot;//构建的单词前缀树
	//在树中插入一个单词的方法实现
	void addWord(string word) {
   
		TrieNode *ptr = trieRoot;//扫描这棵树,将word插入
		//将word的字符逐个插入
		for (auto ch : word) {
   
			if (ptr->children[ch - 'a'] == NULL) {
   
				ptr->children[ch - 'a'] = new TrieNode();
			}
			ptr = ptr->children[ch - 'a'];
		}
		ptr->isWord = true;//标记为单词
	}
public</
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值