当前位置: 首页 > news >正文

“图解”LeetCode 1813. 句子相似性 III

【LetMeFly】:“图解”1813.句子相似性 III

力扣题目链接:https://leetcode.cn/problems/sentence-similarity-iii/

一个句子是由一些单词与它们之间的单个空格组成,且句子的开头和结尾没有多余空格。比方说,"Hello World" ,"HELLO" ,"hello world hello world" 都是句子。每个单词都  包含大写和小写英文字母。

如果两个句子 sentence1 和 sentence2 ,可以通过往其中一个句子插入一个任意的句子(可以是空句子)而得到另一个句子,那么我们称这两个句子是 相似的 。比方说,sentence1 = "Hello my name is Jane" 且 sentence2 = "Hello Jane" ,我们可以往 sentence2 中 "Hello" 和 "Jane" 之间插入 "my name is" 得到 sentence1 。

给你两个句子 sentence1 和 sentence2 ,如果 sentence1 sentence2 是相似的,请你返回 true ,否则返回 false 。

 

示例 1:

输入:sentence1 = "My name is Haley", sentence2 = "My Haley"
输出:true
解释:可以往 sentence2 中 "My" 和 "Haley" 之间插入 "name is" ,得到 sentence1 。

示例 2:

输入:sentence1 = "of", sentence2 = "A lot of words"
输出:false
解释:没法往这两个句子中的一个句子只插入一个句子就得到另一个句子。

示例 3:

输入:sentence1 = "Eating right now", sentence2 = "Eating"
输出:true
解释:可以往 sentence2 的结尾插入 "right now" 得到 sentence1 。

示例 4:

输入:sentence1 = "Luky", sentence2 = "Lucccky"
输出:false

 

提示:

  • 1 <= sentence1.length, sentence2.length <= 100
  • sentence1 和 sentence2 都只包含大小写英文字母和空格。
  • sentence1 和 sentence2 中的单词都只由单个空格隔开。

方法一:双指针

为了方便处理,我们首先将句子拆分为单词。例如将Hello World拆分为[Hello, World]

接着对于单词列表1和单词列表2,分别使用首尾两个指针,指针指向两个单词列表中已经匹配上的部分。

为了方便理解,假设句子1为A E B C,句子2为A E C,那么:

单词1首指针                       单词1尾指针
     ↓                                ↓
           A      E      B        C         👈单词1
           A      E               C         👈单词2
     ↑                                ↑
单词2首指针                       单词2尾指针

接着在单词1和单词2的首指针的下一个单词匹配时,不断后移两个指针

    单词1首指针          单词1尾指针
         ↓                   ↓
A        E      B        C         👈单词1
A        E               C         👈单词2
         ↑                   ↑
    单词2首指针          单词2尾指针

不难发现两个单词列表的第一个单词A是匹配的,第二个单词B也是匹配的,但是第三个单词开始不匹配了。首指针的移动到此为止

接着开始移动尾指针

    单词1首指针      单词1尾指针
         ↓               ↓
A        E      B        C         👈单词1
A        E               C         👈单词2
         ↑               ↑
    单词2首指针      单词2尾指针

不难发现两个单词列表的最后一个单词C是匹配的,但是倒数第二个单词开始不匹配了。尾指针的移动到此为止

指针移动完毕,诶,单词列表2的首位指针相邻了!!!

这说明什么?这说明单词列表2的首指针所指过的单词,全都是单词列表1的“前缀”;而单词列表2的尾指针所指过的单词,全都是单词列表1的“后缀”

那不就说明单词列表1可以由单词列表2在中间添加数个连续的单词而得到么?

因此返回true即可

  • 时间复杂度 O ( l e n ( s e n t e n c e 1 ) + l e n ( s e n t e n c e 2 ) ) O(len(sentence1) + len(sentence2)) O(len(sentence1)+len(sentence2))
  • 空间复杂度 O ( l e n ( s e n t e n c e 1 ) + l e n ( s e n t e n c e 2 ) ) O(len(sentence1) + len(sentence2)) O(len(sentence1)+len(sentence2))

注意事项:

  1. 比较指针的下一个单词之前,记得检测指针的下一个单词是否在单词列表的合法范围内,以防止越界
  2. 在比较尾指针时,不但要保证指针的下一个所指下标大于等于0,还要保证下一个所指位置大于首指针(与首指针不重合,以防止某个单词匹配两次)

AC代码

C++

class Solution {
private:
    vector<string> sentence2words(string& s) {
        vector<string> ans;
        int start = 0;
        for (int i = 0; i <= s.size(); i++) {
            if (i == s.size() || s[i] == ' ') {
                ans.push_back(s.substr(start, i - start));
                start = i + 1;
            }
        }
        return ans;
    }
public:
    bool areSentencesSimilar(string& sentence1, string& sentence2) {
        vector<string> words1 = sentence2words(sentence1), words2 = sentence2words(sentence2);
        int front1 = -1, front2 = -1, back1 = words1.size(), back2 = words2.size();
        while (front1 + 1 < words1.size() && front2 + 1 < words2.size() && words1[front1 + 1] == words2[front2 + 1]) {
            front1++, front2++;
        }
        while (back1 - 1 > front1 && back2 - 1 > front2 && words1[back1 - 1] == words2[back2 - 1]) {
            back1--, back2--;
        }
        return front1 + 1  == back1|| front2 + 1 == back2;
    }
};

Python

class Solution:
    def areSentencesSimilar(self, sentence1: str, sentence2: str) -> bool:
        words1 = sentence1.split()
        words2 = sentence2.split()
        front1, front2, back1, back2 = -1, -1, len(words1), len(words2)
        while front1 + 1 < len(words1) and front2 + 1 < len(words2) and words1[front1 + 1] == words2[front2 + 1]:
            front1 += 1
            front2 += 1
        while back1 - 1 > front1 and back2 - 1 > front2 and words1[back1 - 1] == words2[back2 - 1]:
            back1 -= 1
            back2 -= 1
        return front1 + 1 == back1 or front2 + 1 == back2

同步发文于CSDN,原创不易,转载请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/128710464

相关文章:

  • 我的开源项目之Matlab/Octave转Python工具(motopy)
  • 一个高效的通用光学卫星数据正射校正程序
  • 工作和学习遇到的技术问题
  • kafka常用命令大全
  • Python数据库操作 ---- pymysql教学
  • 【互联网大厂机试真题 - 科大讯飞】
  • Wider Face+YOLOV7人脸检测
  • 点击化学Alkynyl Myristic COOH,82909-47-5,13-十四炔酸
  • 基于“遥感+”蓝碳储量估算、红树林信息提取实践技术应用与科研论文写作
  • 【算法基础】1.8离散化
  • Mysql导出100万条数据,9种导出方法优缺点和速度、文件大小测试
  • 【华为OD机试真题2023 JAVA】Linux发行版的数量
  • [Pytorch]将自己的数据集载入dataloader
  • 【jQuery超快速入门教程】上篇
  • 进程、线程及python的多线程编程
  • 【ESP 保姆级教程】玩转emqx认证篇④ ——使用 Redis 的密码认证
  • 东莞注塑MES管理系统具有哪些功能
  • 云上的米开朗基罗:在不确定时代,寻找建筑般的确定性
  • CSS 布局 - 水平 垂直对齐
  • 【DevOps实战|基于Jenkins与Gitlab构建企业级持续集成环境系统】(更新中未完成)