二、字符串(36)392. 判断子序列

2023-11-19

392. 判断子序列

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

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

进阶:

如果有大量输入的 S,称作 S1, S2, ... , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?

示例 1:

输入:s = "abc", t = "ahbgdc"
输出:true

示例 2:

输入:s = "axc", t = "ahbgdc"
输出:false

提示:

  • 0 <= s.length <= 100
  • 0 <= t.length <= 10^4
  • 两个字符串都只由小写字符组成。

 

我的题解:

class Solution:
    def isSubsequence(self, s: str, t: str) -> bool:
        l1 = len(s)
        l2 = len(t)
        if l1 > l2:
            return False
        elif l1 == l2:
            if s == t:
                return True
            else:
                return False
        else:
            i = 0
            j = 0
            while  i < l1 and j < l2:
                if s[i] == t[j]:
                    i += 1
                j += 1

        if i == l1:
            return True
        else:
            return False

官方题解:

 

 

class Solution:
    def isSubsequence(self, s: str, t: str) -> bool:
        n, m = len(s), len(t)
        i = j = 0
        while i < n and j < m:
            if s[i] == t[j]:
                i += 1
            j += 1
        return i == n



方法二:动态规划

思路及算法

动态规划(英语:Dynamic programming,简称 DP),是一种在数学、管理科学、计算机科学、经济学和生物信息学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。动态规划常常适用于有重叠子问题和最优子结构性质的问题。

动态规划其实就是,给定一个问题,我们把它拆成一个个子问题,直到子问题可以直接解决。然后呢,把子问题答案保存起来,以减少重复计算。再根据子问题答案反推,得出原问题解的一种方法。

一般这些子问题很相似,可以通过函数关系式递推出来。然后呢,动态规划就致力于解决每个子问题一次,减少重复计算,比如斐波那契数列就可以看做入门级的经典动态规划问题。

动态规划核心思想

动态规划最核心的思想,就在于拆分子问题,记住过往,减少重复计算

  • 递归,是从f(10)往f(1)方向延伸求解的,所以也称为自顶向下的解法。
  • 动态规划从较小问题的解,由交叠性质,逐步决策出较大问题的解,它是从f(1)往f(10)方向,往上推求解,所以称为自底向上的解法。

 

 

 

 

 

class Solution:
    def isSubsequence(self, s: str, t: str) -> bool:

'''
m表示该字符没有出现,每一行除了对应的行头的出现位置是本行外,行头之后的元素的第一次出现位置都是从下一行继承而来
'''

        n, m = len(s), len(t)#子串与串的长度
        #['Hi!'] * 4 =	['Hi!', 'Hi!', 'Hi!', 'Hi!']
        #[0] * 26 = [0,0,0,0,0,0,0,0,0,0,0,...,0] 26个0
        #[[0] * 26 for _ in range(m)] = [[0,...,0] , ..., [0,...,0]] m个[0,...,0]
        #构造一个二维矩阵,m行26列
        f = [[0] * 26 for _ in range(m)]# 初始化m个长度为26的列表记录字母a-z的位置
        #	list.append(obj) 在列表末尾添加新的对象
        #[[0,...,0] , ..., [0,...,0], [m,...,m]] m+1
        f.append([m] * 26)#补充,给f[m-1]行用,补充m表示未存在

        #range(5):0-4 range(5,9) :5-8 
        #range(m - 1, -1, -1): m-1 - 0
        #填充矩阵
        for i in range(m - 1, -1, -1):#从后往前m-1 —— 0
            for j in range(26):#从左往右
                # 记录字母a-z在t[i:]中的位置,如果第i个字符等于字符[a-z][j],那么j在i的位置,
                #否则j在t[i+1:]范围,这里倒序遍历,如果j不存在那么f[i][j]的值就是m
                #ord(t[i]) == j + ord('a') : 找到t[i]对应的元素,在该行(a-z)的位置
                #ord(t[i]) != j + ord('a')时  使用f[i + 1][j]的值进行覆盖
                #存放的是a-z 26个字母在t[i]开始之后的出现位置,不存在则记为m
                f[i][j] = i if ord(t[i]) == j + ord('a') else f[i + 1][j]

        #从第0行开始
        add = 0
        for i in range(n):#遍历子串s
            #ord(s[i]) - ord('a')表示s[i]对应的列 == m表示不存在
            if f[add][ord(s[i]) - ord('a')] == m:# 从t的第0个字符开始,如果f[0][j]==m,
                #也就是说字母j不在t内,返回false,[ord(s[i]) - ord('a')]表示j,也就是在f数组中
                #的位置
                return False
            #+ 1是因为f[add][ord(s[i]) - ord('a')]这个位置已经匹配了,从下一行开始
            add = f[add][ord(s[i]) - ord('a')] + 1
        #都在
        return True

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

二、字符串(36)392. 判断子序列 的相关文章

随机推荐

  • word格式问题——英文单词间距太大、文本中嵌入公式导致行距太大、单双栏排版

    1 英文单词直接间距太大 1 全选 右击鼠标 选 段落 中文版式 勾选 允许西文在单词中间换行 如果不勾选此项 可目测换行位置 按住Shift打回车 手动换行 2 选择左对齐 然后用 连接被分割的单词 2 文本中嵌入公式导致行距太大 在段落
  • php的$_SERVER['HOSTNAME']

    一 前言 在最新一次更新代码后 发现代码中出现了 SERVER HOSTNAME 这个东西 关键是 SERVER HTTP HOST 和 SERVER SERVER NAME 我们经常用到 一般是用来获取服务器上的相关参数 唯独这个HOST
  • 写需求分析必须牢记的5大要点

    需求验证的5大要点 要做好需求验证 必须在思想 方法 语言 人员 内容5个要点上做好相应的工作 否则就会产生很多负面的影响 1 思想 前面已经说过 由于Review被翻译成 评审 导致很多人将其与中国人常说的评审相混淆 其实它们之间是有区别
  • CSDN博文显示图片的方法

    感觉官方应该出一个教程的 不然新手第一次发博文十有八九会发现自己的博文发表之后没有图片 既然官方不给 那么自己摸索咯 参考 http blog csdn net cherish cx article details 52782644 1 编
  • 利用Mybatis拦截器对数据库水平分表

    首先你要知道在哪些sql上面要处理分表 你可能需要一个注解 java view plain copy package com dusk domyself stock common split import java lang annotat
  • 数据挖掘知识点总结

    1 数据挖掘产生的背景 驱动力是什么 四种主要技术激发了人们对数据挖掘技术的开发 应用和研究的兴趣 超大规模数据库的出现 如商业数据仓库和计算机自动收集数据记录手段的普及 先进的计算机技术 如更快和更大的计算能力和并行体系结构 对海量数据的
  • 用递归法求两个数的最大公约数

    用递归法求两个数的最大公约数 求两个数的最大公约数的思路是 用辗转现除法 辗转相除法求两个数的最大公约数的步骤如下 先用小的一个数除大的一个数 得第一个余数 再用第一个余数除小的一个数 得第二个余数 又用第二个余数除第一个余数 得第三个余数
  • 虚拟化与网络存储技术

    虚拟化技术简介 一 常见的虚拟化技术分类 1 CPU虚拟化 CPU的虚拟化技术是一种硬件方案 支持虚拟化技术的CPU带有特别优化过的指令集来控制虚拟过程 通过这些指令集 VMM会很容易提高性能 2 服务器虚拟化 服务器虚拟化能够通过区分资源
  • 【手撕代码系列】JS手写实现Promise.all

    公众号 Code程序人生 分享前端所见所闻 Promise all 方法接收一个 Promise 对象数组作为参数 返回一个新的 Promise 对象 该 Promise 对象在所有的 Promise 对象都成功时才会成功 其中一个 Pro
  • mysql数据库中 控制流程函数 case

    1 CASE CASE value WHEN compare value1 THEN result1 WHEN compare value2 THEN result2 ELSE result3 END 解释 用value值来匹配 如果val
  • pcl入门笔记1:pcl的安装

    前言 最近刚入坑pcl 打算记录一下自己的学习历程 安装pcl前的准备 本教程使用的是windows下的预编译包安装 要想顺利编译程序 需要安装好微软的Visual Studio IDE和cmake 这两者安装过程笔者不详细介绍 读者可以自
  • 华为云计算之rainbow迁移原理

    华为云计算之rainbow迁移原理 一 华为rainbow迁移工具适用场景 1 rainbow介绍 2 业务迁移的应用场景 3 业务迁移顺序设计 二 迁移流程图 1 Windows块级迁移原理 2 Linux文件级迁移原理 三 rainbo
  • Dynamics 365应用程序开发 - 6. 使用Microsoft Flow自动化业务流程

    在上一章中 我们了解了如何使用Microsoft PowerApps轻松创建自定义商业应用程序 在本章中 我们将了解Microsoft Flow 它可以定义为一种基于云的服务 使用户能够构建跨多个应用程序和服务自动化不同任务和流程的工作流
  • 常见的Restrictions用法

    Restrictions eq Restrictions ne Restrictions allEq 利用Map来进行多个等于的限制 Restrictions gt Restrictions ge Restrictions lt Restr
  • v-show控制隐藏与显示--案例

    v show简介 1 v show指令的作用是 根据切换元素的显示状态 2 原理是修改元素 的display 实现显示隐藏 3 指令后面的内容 最终都会解析为布尔值 4 值为true元素显示 值为false元素隐藏 除了 v if v sh
  • selenium 获取某元素的 某属性 的值

    selenium 获取某元素的 某属性的值 1 先通过元素定位 获得此元素的 WebElement WebElement yuansu driver findElement By className buttonInput1 text 2
  • 显式的实例化与外部模板的声明

    2 12 2 显式的实例化与外部模板的声明 深入理解C 11 C 11新特性解析与应用 第2章保证稳定性和兼容性 本章中的新特性基本上都遵循了该设计思想 本节为大家介绍显式的实例化与外部模板的声明 作者 Michael Wong IBM X
  • Zookeeper之ZAB协议

    1 概念 Zookeeper使用 种称为Zookeeper Atomic Broadcast ZAB Zookeeper原 消息 播协议 的协议作为其数据 致性的核 算法 ZAB协议并不像Paxos算法那样 是 种通 的分布式 致性算法 它
  • 电脑修改用户(User)文件夹名称

    情景 Windows 11 的用户名与 C 盘 系统盘 中的文件夹名称不对应 可能是由于重装系统导致的 例如我笔记本中系统用户名是 fly 但文件夹名称却是 16490 Step 1 打开Administrator账户 搜索 cmd 右键
  • 二、字符串(36)392. 判断子序列

    392 判断子序列 给定字符串 s 和 t 判断 s 是否为 t 的子序列 字符串的一个子序列是原始字符串删除一些 也可以不删除 字符而不改变剩余字符相对位置形成的新字符串 例如 ace 是 abcde 的一个子序列 而 aec 不是 进阶