Leetcode每日一题练习 ------ 1813. 句子相似性 III

Leetcode 每日一题练习继续讨论:

1813. 句子相似性 III
1813. Sentence Similarity III

题解

本题只能插入一个句子,则要在插入一个句子后将短句变为长句,短句拆分后的前后两部分应分别位于长句的首尾部分(可以拆为空句,这样就是短句完全是长句的开头部分或者结尾部分),则遍历两个句子,匹配开头部分,不匹配时继续向后遍历长句直到可以继续匹配,此时匹配的是短句的后半部分,注意可能存在短句的后半部分的的某部分被重复匹配的情况,即假设短句为aaab,长句可能为aaaaab,因此需要一个指针记录匹配短句后半部分时的起始位置,另外一个指针则进行正常的长短句匹配。

代码

class Solution {
public:
    bool areSentencesSimilar(string sentence1, string sentence2) {
        vector<string> s1;
        vector<string> s2;
        istringstream iss1(sentence1);
        istringstream iss2(sentence2);
        string word;
        while(iss1 >> word){
            s1.push_back(word);
        }
        while(iss2 >> word){
            s2.push_back(word);
        }
        if (s1.size() > s2.size()){
            swap(s1,s2);
        }
        int start = 0;
        for (;start<s1.size();start++){
            if(s1[start] != s2[start]){
                break;
            }
        }
        int tail = start;
        if (tail == s1.size()){
            return true;
        }
        int s2ptr = start;
        // cout << tail << " "<<s2ptr<<" "<<s1.size() << s2.size();
        for(;s2ptr<s2.size();s2ptr++){
            if (tail >= s1.size()){
                tail = start;
            }
            if(s2[s2ptr] != s1[tail]){
                tail = start;
                if(s2[s2ptr] == s1[tail]){
                    tail++;
                }
            }else{
                tail++;
            }
        }
        if (tail == s1.size()){
            return true;
        }
        return false;
    }
};

总结

使用KMP算法应该还可以对字符串匹配的过程做进一步的优化,把每个单词视为kmp中的字母,即可使用同样的方案加速匹配,在这里就不继续改进了。

本题还可采用将短句视为一个双端队列,遍历短句时同时将短句头部和长句头部,短句尾部和长句尾部进行匹配,任意一端匹配成功则弹出一个单词,两端都不匹配的时候结束遍历,判断短句是否已经全部弹出即可得到结果,空则说明可以匹配上,非空则不能匹配上。

class Solution {
public:
    bool areSentencesSimilar(string sentence1, string sentence2) {
        deque<string> v1, v2;
        stringstream ss(sentence1);
        string s;
        while(getline(ss,s,' ')){
            v1.push_back(s);
        }
        stringstream ss2(sentence2);
        while(getline(ss2,s,' ')){
            v2.push_back(s);
        }
        if(v1.size() > v2.size()) swap(v1,v2);
        while(v1.size()){
            if(v1.front() == v2.front()){
                v1.pop_front();
                v2.pop_front();
            } else if(v1.back() == v2.back()){
                v1.pop_back();
                v2.pop_back();
            } else {
                break;
            }
        }
        return v1.empty();
    }
};
4 个赞

来了,刷题佬

1 个赞

感谢你的分享

1 个赞

今天的每日一题不是加油站吗?

2 个赞

看英文版力扣 leetcode.com 这个的每日一题

1 个赞