524. Longest Word in Dictionary through Deleting
Given a string and a string dictionary, find the longest string in the dictionary that can be formed by deleting some characters of the given string. If there are more than one possible results, return the longest word with the smallest lexicographical order. If there is no possible result, return the empty string.
Example 1:
Input:
s = “abpcplea”, d = [“ale”,“apple”,“monkey”,“plea”]
Output:
“apple”
Example 2:
Input:
s = “abpcplea”, d = [“a”,“b”,“c”]
Output:
“a”
Note:
- All the strings in the input will only contain lower-case letters.
- The size of the dictionary won’t exceed 1,000.
- The length of all the strings in the input won’t exceed 1,000.
方法1:sort + two pointers
官方题解:https://leetcode.com/problems/longest-word-in-dictionary-through-deleting/solution/
思路:
首先因为我们优先返回最长的匹配结果,且长度相等时要按照字母序,因此自定义一下比较的优先顺序并将dictionary里的词sort一下。随后对每一个词调用子函数来比较是否是string的subsequence。子函数是经典的判断Is Subsequence。相当于一个双指针函数,遍历string,每次遇到一个word的hit就将i++,当遍历结束后,一定需要word已经从头到尾全部(按顺序)找到了,才能返回true。没有找到任何匹配词返回“”。或者可以用Number of Matching Subsequences 里hash index的优化方法。
易错点:
- 子函数是判断subsequence的经典型。
Complexity
Time complexity: O(n log n + n * l), n 为dictionary大小,l是string的长度。
Space complexity : O(logn). Sorting takes O(\log n)O(logn) space in average case. (why?)
class Solution {
public:
string findLongestWord(string s, vector<string>& d) {
sort(d.begin(), d.end(), [](string & a, string & b){
if (a.size() == b.size()) return a < b;
return a.size() > b.size();
});
for (auto word: d) {
if (isSubseq(word, s)) return word;
}
return "";
}
bool isSubseq(string & word, string & s) {
int i = 0;
for (char c: s) {
if (i < word.size() && c == word[i]) i++;
}
return i == word.size();
}
};
方法2: without sorting
思路:
和上面思路一样,但是省去sort的步骤,因为如果dictionary超大的话还不如线性复杂度。直接记录一个res,每当word符合条件且优于现有res的时候进行替换。
Complexity
Time complexity: O(l * n)
Space complexity: O(1)
class Solution {
public:
string findLongestWord(string s, vector<string>& d) {
string res = "";
for (auto word: d) {
if (isSubseq(word, s) && (word.size() > res.size() || word.size() == res.size() && word < res)) {
res = word;
}
}
return res;
}
bool isSubseq(string & word, string & s) {
int i = 0;
for (char c: s) {
if (i < word.size() && c == word[i]) i++;
}
return i == word.size();
}
};