0.前言
写了整整一个上午,从8点50到11点半。我果然还是太菜了。继续加油吧!!
写在这里,方便回顾。
1.思路
本题共有三种思路.
1.1暴力
使用set存储所有的字符串。
之后遍历每个字符串的子串,如果其在set中存在,则将其移除。
unordered_set<string> list(words.begin(),words.end());
for(auto item:list){
for(int i = 1;i<item.size();i++){
list.erase(item.substr(i));
}
}
int res = 0;
for(auto item:list){
res += item.size()+1;
}
return res;
1.2 字典树
两个对象,一个TireNode,是一个26个对象的数组。一个TireTree主要保存根节点。
class TireNode{
public:TireNode* arr[26];
};
class TireTree{
TireNode* root = new TireNode();
public:
//从后开始遍历
int insert(string str){
TireNode* cur = root;
bool isNew = false;
for(int i = str.size()-1;i>=0;i--){
int c = str[i]-'a';
if(cur->arr[c] == NULL){
cur->arr[c] = new TireNode();
isNew = true;
}
cur = cur->arr[c];
}
return isNew?str.size()+1 : 0;
}
};
class Solution {
public:
static bool cmp(string a,string b){
return a.size() > b.size();
}
int minimumLengthEncoding(vector<string>& words) {
//第二种方式,使用字典树
int res = 0;
TireTree* tree = new TireTree();
sort(words.begin(),words.end(),cmp);
for(auto item:words){
res += tree->insert(item);
}
return res;
}
};
1.3 排序
对每个字符串进行反转,之后进行排序。
如果发现前一个是后一个的子串,就不对其进行操作。否则统计长度。
要加上最后一个的长度
class Solution {
public:
int minimumLengthEncoding(vector<string>& words) {
int size = words.size();
int res = 0;
for(int i = 0;i<size;i++){
reverse(words[i].begin(),words[i].end());
}
sort(words.begin(),words.end());
for(int i = 0;i<words.size()-1;i++){
if(words[i+1].find(words[i]) == 0){
continue;
}else{
res += words[i].size()+1;
}
}
res += (words[size-1].size()+1);
return res;
}
};
2.所学
2.1find_last_of/find_first_of
返回查找的第一个目标对象的尾字符/首字符下标.
如果当前字符串比所查字符串短,则返回当前字符串最后的下标
string a = "time";
string b = "me";
a.find_last_of(b) //3
b.find_last_of(a) //1
2.2 reverse()
可以对数据进行交换,并且修改原数组