请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。实现词典类 WordDictionary :WordDictionary() 初始化词典对象;void addWord(word) 将 word 添加到数据结构中,之后可以对它进行匹配;bool search(word) 如果数据结构中存在字符串与 word 匹配,则返回 true ;否则,返回 false 。word 中可能包含一些 ‘.’ ,每个 . 都可以表示任何一个字母。
字典树的插入
class TrieNode{
public:
vector<TrieNode*> child;
bool isWord;
TrieNode() : child(26, nullptr), isWord(false) {};
~TrieNode() {
for (auto c : child) delete c;
}
};
class WordDictionary {
public:
WordDictionary() {
root = new TrieNode();
}
~WordDictionary() {
delete root;
}
void addWord(string word) {
TrieNode* p = root;
for (char c : word) {
int i = c - 'a';
if (!p->child[i])
p->child[i] = new TrieNode();
p = p->child[i];
}
p->isWord = true;
}
bool search(string word) {
return match(word, root, 0);
}
bool match(string& word, TrieNode* p, int start) {
if (!p) return false;
if (start == word.size()) return p->isWord;
char c = word[start];
if (c != '.') {
return match(word, p->child[c - 'a'], start + 1);
} else {
for (const auto& child : p->child) {
if (match(word, child, start + 1))
return true;
}
}
return false;
}
private:
TrieNode* root;
};
给你一个产品数组 products 和一个字符串 searchWord ,products 数组中每个产品都是一个字符串。请你设计一个推荐系统,在依次输入单词 searchWord 的每一个字母后,推荐 products 数组中前缀与 searchWord 相同的最多三个产品。如果前缀相同的可推荐产品超过三个,请按字典序返回最小的三个。请你以二维列表的形式,返回在输入 searchWord 每个字母后相应的推荐产品的列表。
字典树
struct PreTree{
PreTree():tree(26),word_flag(0){
}
void add(string s){
PreTree * node=this;
for(int i=0;i<s.size();i++){
if(node->tree[s[i]-'a']==nullptr){
PreTree* new_node=new PreTree();
node->tree[s[i]-'a']=new_node;
}
node = node->tree[s[i]-'a'];
}
node->word_flag=1;
}
void backtrace(PreTree*node){
if(node==nullptr){
return;
}
if(ans.size()==3){
return;
}
if(node->word_flag==1){
ans.push_back(tmp);
}
for(int i=0;i<26;i++){
if(node->tree[i]){
tmp+=(i+'a');
backtrace(node->tree[i]);
tmp.pop_back();
}
}
}
vector<string> search(string s){
ans.clear();
tmp.clear();
PreTree * node=this;
int i;
for(i=0;i<s.size();i++){
if(node->tree[s[i]-'a']==nullptr){
return ans;
}
tmp+=(s[i]);
node = node->tree[s[i]-'a'];
}
backtrace(node);
return ans;
}
vector<PreTree*> tree;
int word_flag;
vector<string> ans;
string tmp;
};
class Solution {
public:
vector<vector<string>> suggestedProducts(vector<string>& products, string searchWord) {
PreTree pt;
for(auto s:products){
pt.add(s);
}
vector<vector<string>> ans;
for(int i=1;i<=searchWord.size();i++){
vector<string> tmp=pt.search(searchWord.substr(0,i));
ans.push_back(tmp);
}
return ans;
}
};
给你一个整数数组 nums ,返回 nums[i] XOR nums[j] 的最大运算结果,其中 0 ≤ i ≤ j < n 。进阶:你可以在 O(n) 的时间解决这个问题吗?
class Trie
{
private:
Trie* next[2]={nullptr};
public:
Trie(){}
void insert(int x)
{
Trie *root=this;
for(int i=30;i>=0;i--)
{
int u=x>>i&1;
if(!root->next[u])root->next[u]=new Trie();
root=root->next[u];
}
}
int srearch(int x)
{
Trie *root=this;
int res=0;
for(int i=30;i>=0;i--)
{
int u=x>>i&1;
if(root->next[!u])root=root->next[!u],res=res*2+!u;
else root=root->next[u],res=res*2+u;
}
res^=x;
return res;
}
};
class Solution {
public:
int findMaximumXOR(vector<int>& nums) {
Trie *root=new Trie();
for(auto x:nums)root->insert(x);
int res=0;
for(auto x:nums)
res=max(res,root->srearch(x));
return res;
}
};
给你一个由非负整数组成的数组 nums 。另有一个查询数组 queries ,其中 queries[i] = [xi, mi] 。第 i 个查询的答案是 xi 和任何 nums 数组中不超过 mi 的元素按位异或(XOR)得到的最大值。换句话说,答案是 max(nums[j] XOR xi) ,其中所有 j 均满足 nums[j] <= mi 。如果 nums 中的所有元素都大于 mi,最终答案就是 -1 。返回一个整数数组 answer 作为查询的答案,其中 answer.length == queries.length 且 answer[i] 是第 i 个查询的答案。
字典树插入
class Trie {
public:
const int L = 30;
Trie* children[2] = {};
void insert(int val) {
Trie* node = this;
for (int i = L - 1; i >= 0; --i) {
int bit = (val >> i) & 1;
if (node->children[bit] == nullptr) {
node->children[bit] = new Trie();
}
node = node->children[bit];
}
}
int getMaxXor(int val) {
int ans = 0;
Trie* node = this;
for (int i = L - 1; i >= 0; --i) {
int bit = (val >> i) & 1;
if (node->children[bit ^ 1] != nullptr) {
ans |= 1 << i;
bit ^= 1;
}
node = node->children[bit];
}
return ans;
}
};
class Solution {
public:
vector<int> maximizeXor(vector<int> &nums, vector<vector<int>> &queries) {
sort(nums.begin(), nums.end());
int numQ = queries.size();
for (int i = 0; i < numQ; ++i) {
queries[i].push_back(i);
}
sort(queries.begin(), queries.end(), [](auto &x, auto &y) { return x[1] < y[1]; });
vector<int> ans(numQ);
Trie* t = new Trie();
int idx = 0, n = nums.size();
for (auto &q : queries) {
int x = q[0], m = q[1], qid = q[2];
while (idx < n && nums[idx] <= m) {
t->insert(nums[idx]);
++idx;
}
if (idx == 0) {
ans[qid] = -1;
} else {
ans[qid] = t->getMaxXor(x);
}
}
return ans;
}
};
第二十三天,一天比一天难。