2022-2-14 Leetcode 524.通过删除字母匹配到字典里最长单词

2022-2-14 Leetcode 524.通过删除字母匹配到字典里最长单词_第1张图片
2022-2-14 Leetcode 524.通过删除字母匹配到字典里最长单词_第2张图片
我自己的方法:
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;
    }
};

你可能感兴趣的:(力扣刷题记录,leetcode,算法,职场和发展)