211添加与搜索单词 - 数据结构设计(前缀树+深度优先搜索)

1、题目描述

设计一个支持以下两种操作的数据结构:

void addWord(word)
bool search(word)
search(word) 可以搜索文字或正则表达式字符串,字符串只包含字母 . 或 a-z 。 . 可以表示任何一个字母。

说明:你可以假设所有单词都是由小写字母 a-z 组成的。

2、示例

addWord("bad")
addWord("dad")
addWord("mad")
search("pad") -> false
search("bad") -> true
search(".ad") -> true
search("b..") -> true

3、题解

基本思想:前缀树+深度优先搜索

给每一个字符建立一个前缀树结构,当前字符的后继字符可能是任意26个字母所以有26个孩子,如果截止当前字符构成插入的字符串,置当前字符节点的isWord为true。

搜索过程中,对于'.'的处理,使用深度优先搜索,遍历当前节点所有非空孩子是否最后能匹配上,如果都匹配不上返回false。

前缀树是一个有根的树,其结点具有以下字段:

  • 最多R个指向子结点的链接,其中每个链接对应字母表数据集中的一个字母。本题R为26
  • 布尔字段,以指定节点是对应键的结尾还是只是键前缀。
#include<vector>
#include<iostream>
#include<algorithm>
#include<unordered_set>
using namespace std;
class WordDictionary {
public:
	/** Initialize your data structure here. */
	WordDictionary() {
		//基本思想:前缀树+深度优先搜索
		//给每一个字符建立一个Trie结构,当前字符的后继字符可能是任意26个字母所以有26个孩子
		//如果截止当前字符构成插入的字符串,置当前字符节点的isWord为true。
		//对于'.'的处理,使用深度优先搜索,遍历当前节点所有非空孩子是否最后能匹配上,如果都匹配不上返回false
		//Trie 树是一个有根的树,其结点具有以下字段:
		//最多R个指向子结点的链接,其中每个链接对应字母表数据集中的一个字母。本题R为26
		//布尔字段,以指定节点是对应键的结尾还是只是键前缀。
		for (int i = 0; i < 26; i++)
			child[i] = nullptr;
		isWord = false;
	}

	/** Adds a word into the data structure. */
	void addWord(string word) {
		WordDictionary* t = this;
		for (int i = 0; i < word.size(); i++)
		{
			if (t->child[word[i]-'a'] == nullptr)
				t->child[word[i] - 'a'] = new WordDictionary();
			t = t->child[word[i] - 'a'];
		}
		t->isWord = true;
	}

	/** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */
	bool search(string word) {
		WordDictionary* t = this;
		for (int i = 0; i < word.size(); i++)
		{
			if (word[i] == '.')
			{
				for (int j = 0; j < 26; j++)
				{
					if (t->child[j] != nullptr)
					{
						if (t->child[j]->search(word.substr(i + 1, word.size() - i - 1)) == true)
							return true;
					}
				}
				return false;
			}
			else
			{
				if (t->child[word[i] - 'a'] == nullptr)
					return false;
				t = t->child[word[i] - 'a'];
			}
		}
		return t->isWord;
	}
private:
	WordDictionary* child[26];
	bool isWord;
};
int main()
{
	WordDictionary* obj = new WordDictionary();
	obj->addWord("bad");
	obj->addWord("dad");
	obj->addWord("mad");
	cout << obj->search("a.") << endl;// -> false
	cout << obj->search("pad") << endl;// -> false
	cout << obj->search("bad") << endl;// -> true
	cout << obj->search(".ad") << endl;// -> true
	cout << obj->search("b..") << endl;// -> true
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值