双非刷leetcode备战2023年蓝桥杯,qwq加油吧,无论结果如何总会有收获!一起加油,我是跟着英雄哥的那个思维导图刷leetcode的,大家也可以看看所有涉及到的题目用leetcode搜索就可以哦,因为避让添加外链,一起加油!!!
零基础小白也可以看,因为我就是!
啥叫字典树其实就是找一个前缀相同的东西,是一个类似于树的结构,来保存一个串。
字典树的基本结构:
#include
#include
#include
using namespace std;
class Trie
{
private:
bool isEnd; //判断是否为结尾
Trie *next[26]; //保存着下一个数是26位数哪一个的地址
public:
Trie()
{
isEnd=false;
memset(next,0,sizeof(next));
}
};
这个地方的技巧就是用一个26个字母的数组来标记26个字母哪个存在如果存在就下一个如果不存在就建一个新Trie。这个树的储存结构其实是好多个二十六个字母的Trie的地址组成的。就可以达到快速查找啊插入啊的效果。
如果没有就建一个新Trie,然后下一个肯定有了,然后直接访问下一个就行了,等全访问完了就标记isEnd=true表示这个串插入完了;
void insert(string word) //插入一个字符串
{
Trie *node = this;
for (int i = 0; i < word.length(); i++)
{
if (node->next[word[i] - 'a'] == NULL) //如果没有就新建一个trie;
{
node->isEnd[word[i] - 'a'] = new Trie();
}
node=node->next[word[i]-'a'];//访问下一个;
}
node->isEnd=true;//标记这个trie结束了
}
找串:
从头开始访问,如果有就下一个,如果没有就返回false。如果全访问完了,就返回isEnd;(没访问完就代表没有)
bool search(string word)
{
Trie * node=this;
for (int i = 0; i < word.length(); i++)
{
node =node->next[word[i]-'a'];
if(node==NULL)
{
return false;
}
}
retrun node->isEnd;
}
找串的前缀:
与找串相同不过不需要全访问完了,只要期间都有,把这个前缀访问完了就可以返回true
bool startsWith(string prefix)
{
Trie * node=this;
for (int i = 0; i < word.length(); i++)
{
node =node->next[word[i]-'a'];
if(node==NULL)
{
return false;
}
}
retrun true;
}
题目代码:
class Trie
{
private:
bool isEnd; //判断是否为结尾
Trie *next[26]; //保存着下一个数是26位数哪一个的地址
public:
Trie()
{
isEnd=false;
memset(next,0,sizeof(next));
}
void insert(string word) //插入一个字符串
{
Trie *node = this;
for (int i = 0; i < word.length(); i++)
{
if (node->next[word[i] - 'a'] == NULL) //如果没有就新建一个trie;
{
node->next[word[i] - 'a'] = new Trie();
}
node=node->next[word[i]-'a'];//访问下一个;
}
node->isEnd=true;//标记这个trie结束了
}
bool search(string word)
{
Trie * node=this;
for (int i = 0; i < word.length(); i++)
{
node =node->next[word[i]-'a'];
if(node==NULL)
{
return false;
}
}
return node->isEnd;
}
bool startsWith(string prefix)
{
Trie * node=this;
for (int i = 0; i < prefix.length(); i++)
{
node =node->next[prefix[i]-'a'];
if(node==NULL)
{
return false;
}
}
return true;
}
};
代码(字典树版)
class Trie
{
private:
bool end;
Trie *next[26];
public:
Trie()
{
end = false;
memset(next, 0, sizeof(next));
}
void insertEle(string s)
{
Trie *node = this;
for (int i = 0; i < s.length(); i++)
{
if (node->next[s[i] - 'a'] == NULL)
{
node->next[s[i] - 'a'] = new Trie();
}
node = node->next[s[i] - 'a'];
}
node->end = true;
}
string findSame()
{
Trie *node = this;
string s = "";
while (1)
{
int flag = 0;
int t = 0;
for (int i = 0; i < 26; i++)
{
if (node->next[i] != NULL)
{
flag++;
t = i;
}
}
if (node->end)
{
return s;
}
if (flag == 1)
{
s = s + (char)('a' + t);
node = node->next[t];
}
else
{
return s;
}
}
return s;
}
};
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
Trie* t=new Trie();
while(!strs.empty())
{
t->insertEle (strs.back());
strs.pop_back();
}
return t->findSame();
}
};
class Trie
{
public:
bool end;
Trie *next[26];
Trie()
{
end = false;
memset(next, 0, sizeof(next));
}
};
class WordDictionary
{
private:
Trie *root1;
public:
WordDictionary()
{
root1 = new Trie();
}
void addWord(string word)
{
Trie *root = root1;
for (int i = 0; i < word.length(); i++)
{
if (root->next[word[i] - 'a'] == NULL)
{
root->next[word[i] - 'a'] = new Trie();
}
root = root->next[word[i] - 'a'];
}
root->end = true;
}
bool search(string word)
{
return dfs(root1, word, 0);
}
bool dfs(Trie *root, string &word, int start)
{
if (start == word.length())
{
return root->end;
}
if (word[start] == '.')
{
int flag = 0;
for (int i = 0; i < 26; i++)
{
if (root->next[i])
{
if (dfs(root->next[i], word, start + 1))
{
return true;
}
}
}
}
else if (root->next[word[start] - 'a'] == NULL)
{
return false;
}
else
{
return dfs(root->next[word[start] - 'a'], word, start + 1);
}
return false;
}
};
//这个要注意要把单词少的放在后面
class Trie
{
private:
bool isEnd; //判断是否为结尾
Trie *next[26]; //保存着下一个数是26位数哪一个的地址
public:
Trie()
{
isEnd = false;
memset(next, 0, sizeof(next));
}
void insert(string word) //插入一个字符串
{
Trie *node = this;
for (int i = word.length() - 1; i >= 0; i--)
{
if (node->next[word[i] - 'a'] == NULL) //如果没有就新建一个trie;
{
node->next[word[i] - 'a'] = new Trie();
}
node = node->next[word[i] - 'a']; //访问下一个;
}
node->isEnd = true; //标记这个trie结束了
}
bool startsWith(string prefix)
{
Trie *node = this;
for (int i = prefix.length() - 1; i >= 0; i--)
{
node = node->next[prefix[i] - 'a'];
if (node == NULL)
{
return false;
}
}
return true;
}
};
class Solution {
public:
int minimumLengthEncoding(vector<string>& words) {
for (int i = 0; i < words.size(); i++)
{
for (int j = 0; j < words.size() - i - 1; j++)
{
if (words[j].length() < words[j + 1].length())
{
string t = words[j];
words[j] = words[j + 1];
words[j + 1] = t;
}
}
}//冒泡排序
Trie* root=new Trie();
int count =0;
for(int i=0;i<words.size();i++)
{
if(root->startsWith(words[i]))//如果能找到
{
continue;
}
else
{
root->insert(words[i]);
count+=(words[i].length()+1);
}//如果找不到
}
return count;
}
};
Love is worth years.❤
热爱可抵岁月漫长。
本文部分思路来源于网络如有侵权联系删除~