网站首页 文章专栏 通过删除字母匹配到字典里最长单词
leetcode题号:524
给定一个字符串和一个字符串字典,找到字典里面最长的字符串,该字符串可以通过删除给定字符串的某些字符来得到。如果答案不止一个,返回长度最长且字典顺序最小的字符串。如果答案不存在,则返回空字符串。
示例 1:
输入: s = "abpcplea", d = ["ale","apple","monkey","plea"] 输出: "apple"
示例 2:
输入: s = "abpcplea", d = ["a","b","c"] 输出: "a"
说明:
还是使用哈希表存储字典,然后逐个删除原字符串的某个字符,再递归。 简单的字符串还行,长字符串容易超时。
class Solution { public: bool found = false; string res; void myfind(string s, unordered_map<string, int> &myhash){ if(s.size() > 0){ for(int i = 0; i < s.size(); i++){ auto ptr = myhash.find(s); if(ptr != myhash.end()){ res = ptr->first.size() > res.size() ? ptr->first : res; found = true; }else{ string temp_str = s.substr(0, i) + s.substr(i + 1, s.size() - 1 - i); myfind(temp_str, myhash); } } } } string findLongestWord(string s, vector<string>& d) { unordered_map<string, int> myhash; sort(d.begin(), d.end()); for(int i = 0; i < d.size(); i++) myhash.insert(pair<string, int>(d[i], i)); myfind(s, myhash); return res; } };
有两处做的不够好,一处是使用了递归,导致递归时的时间复杂度变为O(26^n). 第二处是字典序的处理上,虽然进行了排序,但在逐个删除字符寻找匹配时却不是按照字典序,所以字典序相当于没有处理。
下面的解法一是参考题解中的答案,有参考价值。
class Solution { public: bool found = false; string res; // 给原始字符串,看某个单词是否match string mymatch(string s, string mydict){ int i, j; for(i = 0, j = 0; i < s.size() && j < mydict.size(); ){ if(s[i] == mydict[j]) j++; i++; } return j == mydict.size() ? mydict : ""; } string findLongestWord(string s, vector<string>& d) { string res; for(auto m : d){ string temp = mymatch(s, m); if(temp.size() > res.size()) res = temp; else if(temp.size() == res.size()){ if(temp < res) res = temp; } } return res; } };
优点一:自定义match函数,做删除字符的匹配,时间复杂度估计为 O(字典数组的大小 x min(字符串长度, 字典长度));
思考:leetcode将此题列为与最长前缀树相关的题目,是不是可以用最长前缀树解决此题呢?