leetCode208:实现一棵前缀树

目录

一、题目描述

二、解题思路

三、代码实现


一、题目描述

实现一个 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

说明:

  • 你可以假设所有的输入都是由小写字母 a-z 构成的。
  • 保证所有输入均为非空字符串。

二、解题思路

前缀树又叫字典树,是一个多叉树的结构。是由父节点通过指针指向子节点来表示父节点所代表字母的下一个字母是子节点所代表的的字母。按照都是小写字母的要求,任何一个字母的后面可能出现的字母有26个,所以是一个26叉树结构。在这个结构上还需要维护一个bool变量来表示当前字母是否到了单词的结尾,方便查找。

树节点的结构:

//节点的结构
//指针数组形式
class node {
public:
	node* trieNode[26] = { nullptr };
	bool isEnd;
	node() {
		isEnd = false;
	}
	~node() {
		for (int i = 0; i < 26; i++) {
			if (trieNode[i]) {
				delete trieNode[i];
			}
		}
	}
};

前缀树的结构:

class Trie {
public:
	/** Initialize your data structure here. */
	node* root;
	Trie() {
		root = new node();
	}
	~Trie() {
		delete root;
	}

	/** Inserts a word into the trie. */
	void insert(string word) {
	}

	/** Returns if the word is in the trie. */
	bool search(string word) {
	}

	/** Returns if there is any word in the trie that starts with the given prefix. */
	bool startsWith(string prefix) {
	}
};

insert操作:

按照string的字母顺序,一个一个字母的往树里面添加节点,到最后一个字符的时候把isEnd置为true。

void insert(string word) {
		int n = word.size();
		node * p = root;
		for (int i = 0; i < n; i++) {
			int c = word[i] - 'a';
			if (!p->trieNode[c]) {
				p->trieNode[c] = new node();
			}
			p = p->trieNode[c];
		}
		p->isEnd = true;
	}

search操作:

从字符串开头一个一个往下查找。如果存在串中的某个单词不在树中或者结尾标记不为true,则查找失败,不在要查找的单词。

/** Returns if the word is in the trie. */
	bool search(string word) {
		int length = word.size();
		node* p = root;
		for (int i = 0; i < length; i++) {
			int c = word[i] - 'a';
			if (!p->trieNode[c]) {
				return false;
			}
			p = p->trieNode[c];
		}
		return p->isEnd;
	}

startsWith操作:

与search操作类似,只是不需要判断结尾标记,只要每一个单词都存在,则存在这个字符串前缀。

/** Returns if there is any word in the trie that starts with the given prefix. */
	bool startsWith(string prefix) {
		int length = prefix.size();
		node* p = root;
		for (int i = 0; i < length; i++) {
			int c = prefix[i] - 'a';
			if (!p->trieNode[c]) {
				return false;
			}
			p = p->trieNode[c];
		}
		return true;
	}

三、代码实现

整体代码如下:

//节点的结构
//指针数组形式
class node {
public:
	node* trieNode[26] = { nullptr };
	bool isEnd;
	node() {
		isEnd = false;
	}
	~node() {
		for (int i = 0; i < 26; i++) {
			if (trieNode[i]) {
				delete trieNode[i];
			}
		}
	}
};
class Trie {
public:
	/** Initialize your data structure here. */
	node* root;
	Trie() {
		root = new node();
	}
	~Trie() {
		delete root;
	}

	/** Inserts a word into the trie. */
	void insert(string word) {
		int n = word.size();
		node * p = root;
		for (int i = 0; i < n; i++) {
			int c = word[i] - 'a';
			if (!p->trieNode[c]) {
				p->trieNode[c] = new node();
			}
			p = p->trieNode[c];
		}
		p->isEnd = true;
	}

	/** Returns if the word is in the trie. */
	bool search(string word) {
		int length = word.size();
		node* p = root;
		for (int i = 0; i < length; i++) {
			int c = word[i] - 'a';
			if (!p->trieNode[c]) {
				return false;
			}
			p = p->trieNode[c];
		}
		return p->isEnd;
	}

	/** Returns if there is any word in the trie that starts with the given prefix. */
	bool startsWith(string prefix) {
		int length = prefix.size();
		node* p = root;
		for (int i = 0; i < length; i++) {
			int c = prefix[i] - 'a';
			if (!p->trieNode[c]) {
				return false;
			}
			p = p->trieNode[c];
		}
		return true;
	}
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值