我自己的方法:
1、依次从字典里取出每一个单词,在字符串 s 中进行查找。
查找的过程中可能出现的问题有:
- 字母出现多次,只找到最前面的字母,顺序上会有混乱
- 字母都找到了,但是都是同一个字母
简而言之,会出现乱序(顺序不对)和重复的问题(次数不够)。
要解决这两个问题,只需要把查找到的字符之前的字符都删除掉就行了。
这样做可能会影响到效率的地方有:
- 删除的空间移动
- 拷贝构造函数的多次调用
class Solution {
public:
string findLongestWord(string s, vector<string>& dictionary) {
int maxlen = 0;
string ret;
for(auto & str:dictionary){
if(str.size() > s.size())
continue;
int len = 0;
string copy = s;
for(auto& ch:str){
int pos =copy.find(ch);
if(pos != copy.npos){
copy.erase(0,pos+1);
len++;
}
else break;
}
if(len == str.size()){
if(maxlen < len){
maxlen = len;
ret = str;
}
else if(maxlen == len){
ret = (ret < str ? ret:str);
}
}
}
return ret;
}
};
参考别人的写法
先对 dictionary 里面的单词进行排序,从长到短,相同长度的字符序在前面。
- 较长的单词,字典序号较小的单词放在前面,早搜索到早返回,能够节约时间。
(一个做题时候对字符串的处理能够节约时间的规律,把可能符合题目要求的单词放在前面)
使用双指针同时对 s 和 dictionary 里面的字符串进行比较。
- 双指针可以从两个字符串的单向进行。如果 s 中的单词不符合条件直接向前移动就好了。
- 解决了查找的顺序不对,查找可能存在的重复查找的问题。
- 没有多次拷贝和删除提升了效率
class Solution {
public:
string findLongestWord(string s, vector<string>& dictionary) {
auto cmp = [&](const string &a,const string &b){
if(a.size() == b.size())
return a < b;//如果相同的长度就按照字典序列排序
else return a.size() > b.size();
};
//如果没有就按照字符串较长的顺序排序,
sort(dictionary.begin(),dictionary.end(),cmp);
//将容器里面的按照长度排序
int ps = 0,pd = 0,s_len = s.size();
int dw_len = 0;
for(int i = 0;i < dictionary.size();i++){//遍历字典中的字符串
dw_len = dictionary[i].size();//获取每一个字符串中的长度
while(ps < s_len && pd < dw_len){
if(s[ps] == dictionary[i][pd]){
if(pd == dw_len - 1)
return dictionary[i];//返回找到的字符串
pd++;//当前字典中的指针移动到下一个
}
ps++;//匹配被查找字符串的下一个字符
}
ps = 0;
pd = 0;
//再重新进行字符串中下一个字符的比较的时候,将所有的指针移动到起点。
}
return "";
//这个题目有一个关键点是s字符串中的顺序比较,而不是其他的比较
}
};
自己的写法:这道题是归并的数组排序的题的变种,s 可以看成是 dictionary 当中的数组和另外一个数组合并而来,故可以使用双指针。
class Solution {
public:
string findLongestWord(string s, vector<string>& dictionary) {
string ret;
int len = s.size();
for(auto &str : dictionary){
int a = 0;
int b = 0;
int len2 = str.size();
while(a < len && b < len2){
if(str[b] == s[a]){
b++;
a++;
}else {
a++;
}
}
if(b == len2){
if(len2 > ret.size()){
ret = str;
}else if(len2 == ret.size()){
ret = ret > str ? str : ret;
}
}
}
return ret;
}
};