给定一个字符串和一个字符串字典,找到字典里面最长的字符串,该字符串可以通过删除给定字符串的某些字符来得到。如果答案不止一个,返回长度最长且字典顺序最小的字符串。如果答案不存在,则返回空字符串。
示例 1:
输入: s = "abpcplea", d = ["ale","apple","monkey","plea"] 输出: "apple"
示例 2:
输入: s = "abpcplea", d = ["a","b","c"] 输出: "a"
说明:
- 所有输入的字符串只包含小写字母。
- 字典的大小不会超过 1000。
- 所有输入的字符串长度不会超过 1000。
思路一:先给字符串数组排序,排序规则是先按照长度排序(先长后短),如果长度相同则按照字符的ascll码排序(小的在前)。排序后遍历字符数组中的每个字符串str,对每个字符串初始化变量i=0作为计数器,然后对待查找的字符串挨个查找如果对应字符是否相等,如果相等就i++,最后比较i是否等于str的长度,如果等于把str赋值给res,直接返回res即可,因为字符串数组已经排过序了,所以找到的一定是长度最长的字符串。这个方法的时间复杂度是:O(n*log(n)*x+n*x) 这里的n表示d的字符串的数量,x表示待查找字符串的平均长度,空间复杂度是O(logn),因为排序需要logn的额外空间
参考代码:
class Solution {
public:
string findLongestWord(string s, vector<string>& d) {
string res = "";
sort(d.begin(), d.end(), [](string a, string b) {
if (a.size() == b.size()) return a < b;
return a.size() > b.size();
});
for (string str : d) {
int i = 0;
for (char c : s) {
if (i < str.size() && str[i] == c) i++;
}
if (i == str.size()) {
res = str;
return res;
}
}
return res;
}
};
思路二:不采用排序,思路和上面一样,但是更新res的规则需要改变,当str的长度大于res的长度或者与str的长度相等但是字符的ascll码比res靠前,这两种情况需要更新res。这么做的时间复杂度是:O(x*n),x是字符串数组的长度,n是待查找字符串的平均长度,空间复杂度是O(n),n表示返回值res的长度。
参考代码:
class Solution {
public:
string findLongestWord(string s, vector<string>& d) {
string res = "";
for (string str : d) {
int i = 0;
for (char c : s) {
if (i < str.size() && str[i] == c) i++;
}
if (i == str.size() && str.size() >= res.size()) {
if (str.size() > res.size() || (str.size() == res.size() && str < res)) {
res = str;
}
}
}
return res;
}
};