题目链接:力扣https://leetcode-cn.com/problems/longest-word-in-dictionary-through-deleting/
题意:
给你一个字符串 s 和一个字符串数组 dictionary 作为字典,找出并返回字典中最长的字符串,该字符串可以通过删除 s 中的某些字符得到。
如果答案不止一个,返回长度最长且字典序最小的字符串。如果答案不存在,则返回空字符串。
方法一:排序+双指针
class Solution {
private:
static bool cmp(string a,string b)
{
if(a.size()==b.size())
return a<b;//返回字典序在前的
return a.size()>b.size();//从大到小排序
}
public:
string findLongestWord(string s, vector<string>& dictionary) {
string res = "";//初始化要返回的字符串为空
int size = dictionary.size();
sort(dictionary.begin(),dictionary.end(),cmp);
int len = s.size();//存储s的长度
for(int i=0;i<size;i++)
{
if(len<dictionary[i].size()) continue;//假如s的长度比当前字符串短就跳过
int left=0,index=0;//左指针指向s的左侧,index指向当前串的左侧
while(left<len&&index<dictionary[i].size())//s的每个字符没有枚举完并且字典里的第i个词语没有枚举完
{
if(s[left]==dictionary[i][index]) index++;//匹配到了,index自加
left++;//每一轮左指针都自加
}
if(index==dictionary[i].size()) return dictionary[i];
}
return res;//返回结果
}
};
方法二:双指针+判断
class Solution {
public:
string findLongestWord(string s, vector<string>& dictionary) {
string res = "";//初始化要返回的字符串为空
int size = dictionary.size();
int len = s.size();//存储s的长度
for(int i=0;i<size;i++)
{
if(len<dictionary[i].size()) continue;//假如s的长度比当前字符串短就跳过
int left=0,index=0;//左指针指向s的左侧,index指向当前串的左侧
while(left<len&&index<dictionary[i].size())//s的每个字符没有枚举完并且字典里的第i个词语没有枚举完
{
if(s[left]==dictionary[i][index]) index++;//匹配到了,index自加
left++;//每一轮左指针都自加
}
if(index==dictionary[i].size())
{
if(dictionary[i].size()>res.size()) res = dictionary[i];
if(dictionary[i].size()==res.size()&&dictionary[i]<res) res = dictionary[i];
}
}
return res;//返回结果
}
};
方法三:动态规划,dp[i][j]存储第i个位置之后,出现字符j+'a'的位置
class Solution {
public:
string findLongestWord(string s, vector<string>& dic) {
int size = s.size();//获取s的长度
vector<vector<int>> dp(size+1,vector<int>(26,-1));//动态规划向量,dp[i][j]表示第i个元素之后的'a'+j的字符出现的位置
string res = "";
int num = dic.size();//获取字典中单词的个数
for(int i=0;i<size;i++)//枚举每个位置
{
for(int j=i;j<size;j++)//枚举后面的每个位置
{
if(dp[i][s[j]-'a']==-1) dp[i][s[j]-'a'] = j;//假如找到了一个没出现过的字符,就更新它的位置
}
}
for(int i=0;i<num;i++)//枚举词典中的每个词
{
int index = 0;//存储当前匹配到s的哪个位置
int j=0;
for(j=0;j<dic[i].size();j++)//枚举词典中当前词的每个字符
{
if(dp[index][dic[i][j]-'a']!=-1)//当后面有出现我们要的字符,就更新index
{
index = dp[index][dic[i][j]-'a']+1;//更新index
}else
{
break;//匹配不到就退出循环
}
}
if(j==dic[i].size())
{
if(dic[i].size()>res.size()) res = dic[i];//长度更长就更新
if(dic[i].size()==res.size()&&dic[i]<res) res = dic[i];//长度相等,取字典序在前的
}
}
return res;//返回结果
}
};