简单快速实现子序列的判断

2023-10-27

 

针对力扣的判断子序列题目进行算法实现。原题链接可以点击地址:https://leetcode-cn.com/problems/is-subsequence/

基于近两年较火的力扣leetcode刷题训练站点,本人为了能够保持算法和数据结构这些底层计算机知识的基础牢固性,也时不时刷刷里面的题目,让自己的算法能力得到一个很好的锻炼,正所谓,“玉不琢不成器,人不学不知道”嘛。

这里我不想说太多,但是,练习多了,确实有一个很好的感悟。你会发现,所谓的这些算法,无论是针对数据结构的,还是针对数据处理的,提炼出来,都可以当作我们的人生算法,让我们能够更好地成长。像动态规划、贪婪算法、分而治之、递归、回溯等等。

以贪婪算法举例,我个人觉得这就是一个很好的策略。贪婪算法,说的就是获取局部的最优解,进而能够获取全局的最优解。人活在这个世界上,哪有那么容易一开始就能够获取最后美好结果的事情呢。我们长大到现在,实际上,都是一点一点地走过来,一步一步地做出各种选择。只不过这里面,作出了最好的那个选择,可能走得就要好一点,作出了坏一点的选择,就稍微要麻烦一些。那么,我们应该把握好当前能够获取的最优解,当一个个局部的最优解组合在一起时,能够获得最后的整体最优解。当然,凡是无绝对,但是,我觉得这个贪婪策略,还是适用于大部分情况的。

好了,不扯算法策略了。


题目如下:

判断子序列

给定字符串 s 和 t ,判断 s 是否为 t 的子序列。

你可以认为 s 和 t 中仅包含英文小写字母。字符串 t 可能会很长(长度 ~= 500,000),而 s 是个短字符串(长度 <=100)。

字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。

示例 1:
s = "abc", t = "ahbgdc"

返回 true.

示例 2:
s = "axc", t = "ahbgdc"

返回 false.
 


这里想说说的是,力扣官网有时候给出的权威题解,并不是最好的,你可以去看看其他的题解,获取更好的方法。对于该题而言,官方给出了双指针的算法,但是,我个人认为时间复杂度非常不好,因为需要执行最长字符串的长度次数,有点耗费计算机性能。当然了,对于现在的计算机而言,这个根本不算什们。但是,为了学习的话,我觉得还是需要去好好比较一下下的。

这里先给出官方的双指针思路及算法解释,当然,你也可以直接跳过我这里去看力扣官网的题解(官方解释)。

双指针方法的思路

本题询问的是,s 是否是 t 的子序列,因此只要能找到任意一种 s 在 t 中出现的方式,即可认为 s 是 t 的子序列。而当我们从前往后匹配,可以发现每次贪心地匹配靠前的字符是最优决策。

假定当前需要匹配字符 c,而字符 c 在 t 中的位置 x1 和 x2 出现(x1 < x2),那么贪心取 x1 是最优解,因为 x2 后面能取到的字符,x1也都能取到,并且通过 x1与 x2之间的可选字符,更有希望能匹配成功。

这样,我们初始化两个指针 i 和 j,分别指向 s 和 t 的初始位置。每次贪心地匹配,匹配成功则 i 和 j 同时右移,匹配 s 的下一个位置,匹配失败则 j 右移,i 不变,尝试用 t 的下一个字符匹配 s。

最终如果 i 移动到 s 的末尾,就说明 s 是 t 的子序列。

以Java代码为例,官方实现如下

class Solution {
    public boolean isSubsequence(String s, String t) {
        int n = s.length(), m = t.length();
        int i = 0, j = 0;
        while (i < n && j < m) {
            if (s.charAt(i) == t.charAt(j)) {
                i++;
            }
            j++;
        }
        return i == n;
    }
}

接下来分享本人的算法实现(力扣地址

第一,以最短字符串为基准,循环迭代,分别获取位置由小到大的字符;
第二,设置字符串t的指针位置index,用于判断s的字符是否处于字符串t中的指针位置index到字符串尾部;
第三,如果s的字符处于字符串t的指定字符串范围中,则index加1,不断重复该操作;
第四,如果s的字符不处于字符串t的指定字符串范围中,则直接返回false;

这里先不解释太多,直接上代码

class Solution {
    public boolean isSubsequence(String s, String t) {
        if(s.length() > t.length()) return false;
        int index = 0;
        for(int i=0;i<s.length();i++){
            // if exists next index positioin
            if((index = t.indexOf(String.valueOf(s.charAt(i)),index) + 1) == 0){
                return false;
            }
        }
        return true;
    }
}

相比于官方推荐的双指针,我这里稍微改变了一下,只是设置一个单独的指针,用于限定字符串的范围,进而判断出相应字符是否处于该字符串的范围内。

同时,循环遍历,是以最小的字符串为主,也就是待比较的子序列。这样,可以减少循环的次数,减少算法运行时间,虽然,这个时间对于计算机而言,可以忽略不计。我们也要以严谨的态度去研究和实现它。

在官网测试提交之后,得到了一个不错的结果。这也是判断算法优劣的标准。你或许已经想到了,那就是时间和空间复杂度。但从时间和空间复杂度考虑的话,实际上本人提供的算法和官方的算法是一样的。那就是时间复杂度为O(n),空间复杂度为O(1)。好像也看不出什么优劣出来。那么,我再比对一下执行效率吧,这是基于力扣站点反馈的信息。这里,你也可以自己去官方站点验证。

官方双指针的执行效率如下

 

本人的算法执行效率如下

 

故,算法没有最好,只能更好,相信,一定会有比我这个更加厉害的算法实现,也希望大家一起交流讨论。我想说,软件研发里面包含的思想,真的会对人生有着极大的用处。为什么,因为所有的思想落地,不就是通过软件落到实处了嘛。你会了分而治之,面对各种复杂的问题,还有什么担心的呢?你明白了贪婪策略,是不是就不会那么纠结了,就直接选择当下你最优的解就好。

最后,感谢你看到了这里,谢谢。

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

简单快速实现子序列的判断 的相关文章

随机推荐

  • linux中的ldd命令简介

    在linux中 有些命令是大家通用的 比如ls rm mv cp等等 这些我觉得没有必要再细说了 而有些命令 只有开发人员才会用到的 这类命令 作为程序员的我们 是有必要了解的 有的甚至需要熟练使用 有的人总说 这些命令不重要 用的时候去查
  • Elasticsearch基础学习笔记

    目录 一 全文搜索 1 数据分类 2 搜索分类 3 什么是全文搜索 全文检索是指 倒排索引 二 ElasticSearch简介 1 ElasticSearch是什么 2 ElasticSearch特点 3 ElasticSearch版本特性
  • C++学习(三三八)RSP文件

    RSP Response Text File 是一种资源文件 用编程软件或文本编辑工具可以打开 如VC Notepad等等 RSP 文件包含一个或多个命令行参数 由包含在 NET 编译器平台 也称为Roslyn 中的C 编译器 CSC 使用
  • dns服务器修改解析地址,dns服务器修改解析地址

    dns服务器修改解析地址 内容精选 换一换 obsutil是适用于Windows macOS和Linux操作系统的命令行工具 支持通过配置内网DNS服务器地址的方式 使在华为云上的Linux ECS通过内网直接访问OBS 下面将介绍其具体操
  • 内中断

    1 CPU根据中断码如何找到中断处理程序 要定位中断处理程序 就需要找到中断处理程序的段地址和偏移地址 如果根据中断码找到他们 这就引入中断向量表 CPU用8位的中断类型码通过中断向量表找到相应的中断处理程序的入口地址 2 使用中断类型码找
  • OpenCV实战(五)——对象简单计数

    现在我们用OpenCV来计数图像当中的目标物体数目 针对各个物体之间没有粘连的情况 include
  • 离散数学 --- 谓词逻辑 --- 谓词合式公式推理

    第一部分 推理形式和推理规则 1 谓词在拥有命题演算的基本蕴含公式的同时 还有着自己独有的基本蕴含公式 当我们的描述在个体和整体之间转换时 就需要进行量词的消去和添加 1 全称特指规则 US规则 其实就是全称量词消去规则 2 全称量词消去有
  • docker-compose

    能做什么 一个用来把 docker 自动化的东西 有了 docker compose 你可以把所有繁复的 docker 操作全都一条命令 自动化的完成 通过创建compose文件 YUML语法 在这个文件上面描述应用的架构 如使用什么镜像
  • 《零基础入门学习Python》(6)--Python之常用操作符

    前言 Python当中常用操作符 有分为以下几类 幂运算 正负号 算术操作符 比较操作符 lt lt gt gt 逻辑运算符 not and or 操作符介绍 幂运算 gt gt gt 3 3 27 正负号 幂运算的优先级比较特殊 因为幂操
  • 凸多边形面积_C++计算任意多边形的面积

    任意多边形的面积计算 拾忆楓灵的博客 CSDN博客 blog csdn net 计算任意多边形的面积 tenos 博客园 www cnblogs com 完美解决计算3D空间任意多边形面积 Studiouss的博客 CSDN博客 blog
  • 微信小程序开发实战 ②〇(Npm包)

    作者 SYFStrive 作者 SYFStrive 博客首页 HomePage 微信小程序 个人社区 欢迎大佬们加入 社区链接 觉得文章不错可以点点关注 专栏连接 感谢支持 学累了可以先看小段由小胖给大家带来的街舞 微信小程序 目录 什么是
  • React 性能优化完全指南,将自己这几年的心血总结成篇!

    作者 MoonBall 原文地址 https juejin cn post 6935584878071119885 本文分为三部分 首先介绍 React 的工作流 让读者对 React 组件更新流程有宏观的认识 然后列出笔者总结的一系列优化
  • MUMPS 安装

    Centos 7 Install MUMPS 1 下载安装包 需要提交申请 http mumps enseeiht fr 2 安装并行版MUMPS需要以下一些依赖包 MPI BLAS library BLACS library ScaLAP
  • C语言种根号怎么表示 比如(1-x)的二分之一次方

    库函数sqrt x include
  • 5.39 综合案例2.0 - STM32蓝牙遥控小车3(摇杆控制)

    综合案例2 0 蓝牙遥控小车1 摇杆控制 成品展示 案例说明 器件说明 小车连线 小车源码 PS2摇杆手柄 遥控连线 摇杆代码 成品展示 用python开发板和stm32制作一个摇杆控制蓝牙全向智能车 源码开放 案例说明 用STM32单片机
  • 《计算机网络》期末模拟考试练习+答案

    期末考试模拟试题参考 一 单选题 共20题 20分 1 下列有线传输介质中抗电磁干扰最好的是 A 屏蔽双绞线 B 同轴电缆 C 非屏蔽双绞线 D 光纤 正确答案 D 解析 2 TELNET通过TCP IP协议在客户机和远程登录服务器之间建立
  • struct和typedef struct的用法解析

    1 首先 注意在C和C 里不同 在C中定义一个结构体类型要用typedef typedef struct Student int a Stu 于是在声明变量的时候就可 Stu stu1 如果没有typedef就必须用struct Stude
  • Calendar对象获取当前周的bug

    项目场景 双周项目管理 需要获取当前周为一年之中的第几周 原先的代码是用Calendar对象 先用setTime 把当前时间传入 再用get 3 获取一年中的第几周 问题描述 实际发现会比真实的周少一点 且时间是周日到周六为一周 原因分析
  • python:pyqt5的基本使用

    文章目录 基本框架 程序启动画面 一 设置主界面 1 窗体字体设置 2 界面设置 二 设置控件 1 QMessageBox消息框 2 文本编辑框和文本浏览框 3 各种按钮 4 标签 5 单行文本框 6 下拉选择框和数字调节框 7 滑动条和旋
  • 简单快速实现子序列的判断

    针对力扣的判断子序列题目进行算法实现 原题链接可以点击地址 https leetcode cn com problems is subsequence 基于近两年较火的力扣leetcode刷题训练站点 本人为了能够保持算法和数据结构这些底层