一、字典树(Trie)
class Trie
{
private:
vector<Trie*> children;
bool isEnd;
public:
Trie():children(26,nullptr),isEnd(false){}
~Trie()
{
for (Trie* child : children)
{
if (child)delete child;
}
}
void insert(string word)
{
Trie* p = this;
for (char ch : word)
{
if (!p->children[ch - 'a']) p->children[ch - 'a'] = new Trie();
p = p->children[ch - 'a'];
}
p->isEnd = true;
}
bool search(string word)
{
Trie* p = this;
for (char ch : word)
{
if (!p->children[ch - 'a']) return false;
p = p->children[ch - 'a'];
}
return p->isEnd;
}
bool startsWith(string prefix)
{
Trie* p = this;
for (char ch : prefix)
{
if (!p->children[ch - 'a']) return false;
p = p->children[ch - 'a'];
}
return true;
}
};
二、前缀('.')匹配的字典树
class TrieNode
{
public:
vector<TrieNode*> children;
bool isWord;
//表示每一个节点的子结点都是26个字符组成
TrieNode() :children(26, nullptr), isWord(false) {};
//手动释放内存,Vector不能自动释放指针,只能自动释放对象
~TrieNode()
{
for (TrieNode* child : children)
{
if (child)
delete child;
}
}
};
class WordDictionary
{
public:
WordDictionary()
{
root = new TrieNode();
}
~WordDictionary()
{
delete root;
}
void addWord(string word)
{
TrieNode* p = root;
for (char ch : word)
{
//如果在该节点的children中没有这个字符ch就新建一个节点
//因为children代表的是子树的26个字符的指针的数组(Vector)
//所以索引就是ch-'a'的大小
if (!p->children[ch - 'a'])
p->children[ch - 'a'] = new TrieNode();
//有这个字符就将p移动到该字符
p = p->children[ch - 'a'];
}
//插入单词结束后标记当前节点为单词的结尾
p->isWord = true;
}
bool search(string word)
{
TrieNode* p = root;
//index表示从字符串的第一个字符开始匹配搜索,表示的是字符串中的字符索引从0开始
int index = 0;
return searchHelper(word, index, p);
}
bool searchHelper(const std::string& word, int index, TrieNode* node)
{
//如果字符串中的每一个字符都比较之后
if (index == word.size())
return node->isWord;
//这里取出每个索引对应的字符值进行比较
char ch = word[index];
// 如果没有通配符 '.', 则递归搜索相应字符的子节点
if (ch != '.')
{
TrieNode* child = node->children[ch - 'a'];
return child && searchHelper(word, index + 1, child);
}
else// 如果遇到通配符 '.', 则递归搜索所有子节点
{
for (TrieNode* child : node->children)
{
if (child && searchHelper(word, index + 1, child))
return true;
}
}
return false;
}
private:
TrieNode* root;
};
四、只出现一次的数字(位的异或运算)
class Solution
{
public:
int singleNumber(vector<int>& nums)
{
int res = 0;
for (int num : nums)
{
res = res ^ num;
}
return res;
}
};