LeetCode第208题实现 Trie (前缀树)

原题如下:

实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作。

示例:

Trie trie = new Trie();

trie.insert(“apple”);
trie.search(“apple”); // 返回 true
trie.search(“app”); // 返回 false
trie.startsWith(“app”); // 返回 true
trie.insert(“app”);
trie.search(“app”); // 返回 true

一个很容易想到的方法就是把每个str 插入到map里,但是startsWith()函数却不好查!!当然你也可以尝试一下再开一个map把每个str的【0-i】(i>=0&&i<=str.size()-1)存进去(LZ是没有试过。。。。)

其实 这道题就是图的深度优先遍历和广度优先遍历的集合,只不过,我们不要直接把str存进去,把str的每个元素接在他前面那个元素的后面(如果当前元素已经存在,可以省略当前这一步)
举个例子 对于 abc app adx bc 这3个str而言他们构成的 map 集是这样的
a
/|\
b p d
| | |
c p x

  b
  |
  c

注意这个bc
即每个单词的开头为一个图的入口,进入这个图后,对于一个str 我们广度优先遍历找到str【i】,再向下深度遍历str【i+1】,,insert构造这个图的时候也是同样道理

代码如下ps(lz为了偷懒,又开了一个unordered_map<>search_str,便于查str,按照start_with()思绪继续查下去,就是search()):

struct Trie_node
{
	char val;
	vector<Trie_node*>next;
	Trie_node(char x) :val(x){}
};
class Trie {
public:
	/** Initialize your data structure here. */
	Trie() {
	}
	/** Inserts a word into the trie. */
	Trie_node* find_or_insert(vector<Trie_node*> &next, char &a){
		if (next.size() == 0){
			Trie_node *tmp = new Trie_node(a);
			next.push_back(tmp);
			return tmp;
		}
		else{
			for (int i = 0; i <= next.size() - 1; i++){
				if (next[i]->val == a) return next[i];
			}
			Trie_node *tmp = new Trie_node(a);
			next.push_back(tmp);
			return tmp;
		}
	}
	void insert(string word) {
		search_str[word]++;
		unordered_map<char, Trie_node *>::iterator iter = my_map.find(word[0]);
		if (iter == my_map.end()){
			Trie_node *head = new Trie_node(word[0]);
			Trie_node *p = head;
			for (int i = 1; i <= word.size() - 1; i++)
			   p = find_or_insert(p->next, word[i]);
			my_map[word[0]] = head;
		}
		else{
			Trie_node *p = (*iter).second;
			for (int i = 1; i <= word.size() - 1; i++)
			 p = find_or_insert(p->next, word[i]);
		}
	}
	/** Returns if the word is in the trie. */
	bool search(string word) {
		unordered_map<string, int>::iterator iter = search_str.find(word);
		if (iter == search_str.end())return false;
		else return true;
	}
	/** Returns if there is any word in the trie that starts with the given prefix. */
	Trie_node* only_find(vector<Trie_node*> &next, char &a){
		if (next.size() == 0)
			return nullptr;
		else{
			for (int i = 0; i <= next.size() - 1; i++){
				if (next[i]->val == a) return next[i];
			}
			return nullptr;
		}
	}
	bool startsWith(string prefix) {
		unordered_map<char, Trie_node *>::iterator iter = my_map.find(prefix[0]);
		if (iter == my_map.end())return false;
		Trie_node *p = (*iter).second;
		for (int i = 1; i <= prefix.size() - 1; i++){
			p = only_find(p->next, prefix[i]);
			if (p == nullptr)return false;
		}
		return true;
	}
private:
	unordered_map<char, Trie_node *>my_map;
	unordered_map<string, int>search_str;
};
    原文作者:Trie树
    原文地址: https://blog.csdn.net/qq_42203013/article/details/83153449
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注