首页 > 其他分享 >验证子序列(动态规划)

验证子序列(动态规划)

时间:2024-03-14 22:29:30浏览次数:17  
标签:字符 验证 int 位置 start 序列 动态 dp

验证子序列(动态规划)

392. 判断子序列 - 力扣(LeetCode)

题目描述:

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

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

进阶:

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

思路

​ 这是一道基础的动态规划练习题,考虑到有 1 0 9 10^9 109以上数量级的输入,则不可能遍历这么多次T字符串,为了节省时间,我们可以对T进行预处理,转而遍历较短的S串。那么我们需要知道,在T的某个位置i后的某一个字符j在哪个位置第一次出现,如此可以直接跳转到那个位置,继续匹配S串的下一个字符。

​ 由于需要知道下一个字符j在哪里出现,那么显然我们需要从后往前遍历,并不断更新j的合理位置,则dp数组如下定义:

d p [ i ] [ j ] , i 表示位置, j 表示字符 d p [ i ] [ j ] = { i t [ i ] = j d p [ i + 1 ] [ j ] t [ i ] ! = j dp[i][j],i表示位置,j表示字符\\ dp[i][j]=\begin{cases} i& t[i]=j\\ dp[i+1][j]&t[i]!=j \end{cases} dp[i][j],i表示位置,j表示字符dp[i][j]={idp[i+1][j]​t[i]=jt[i]!=j​
如果当前位置是字符j,则更新为当前位置,如果不是,则更新为后一位的j字符位置,这就是转移方程。

在后续验证的时候,可以用start记录开始匹配的位置,每次匹配完成都要在匹配后的下一个位置开始,否则可能会无限循环,给出错误的判断。

代码实现

    bool isSubsequence(string s, string t) {
        int len =t.size();//考虑到题目所说的巨量s,可以预先对t进行处理
        if(len<s.size()) return false;
        vector<vector<int>>dp (len+1,vector<int>(26,-1));
        //dp的思路:从后往前,因为我们想要记录某一字母在后面第一次出现的位置
        //对于dp[i][j],i表示位置,j表示字符,如果t[i]=j,则dp[i][j]=i
        //如果t[i]!=j,dp[i][j]=dp[i+1][j](i位置不为j,则值为后一位的值),依次dp即可
        //注意从后面开始
        int index;
        for(int i =len-1;i>=0;i--){
            index = t[i]-'a';
            dp[i][index]=i;
              for(int j =0;j<26;j++){
                  if(j!=index) dp[i][j]=dp[i+1][j];
            }
        }
        int alpha,start=0;
        for(int i =0;i<s.size();i++){
            alpha=s[i]-'a';
            if(dp[start][alpha]==-1) return false;
            start = dp[start][alpha]+1;//跳过自己,否则遇到连续的相同字符会出错
        }//s从头开始比较,更新为最近的位置,如果为-1,说明不匹配
        return true;
    }

标签:字符,验证,int,位置,start,序列,动态,dp
From: https://blog.csdn.net/shiki217_/article/details/136723811

相关文章

  • (精读)揭示多元时间序列的高阶组织
    原标题《Unveilingthehigher-orderorganizationofmultivariatetimeseries》低阶依赖关系:通过马尔科夫链的模型或分解机FM的模型建模分析;高阶依赖关系:(跨多个用户项交互的复杂多级级联依赖关系)(1)基于马尔科夫链方法建模;(2)基于RNN方法;局限性:模型参数的数量随阶数呈......
  • lc1755 最接近目标值的子序列和
    给你一个整数数组nums和一个目标值goal,需要从nums中选出一个子序列,使子序列元素总和最接近goal,返回abs(sum-goal)可能的最小值。数组的子序列指通过移除原数组中的某些元素(可能全部或无)而形成的数组。1<=nums.length<=40;-1e7<=nums[i]<=1e7;-1e9<=goal<=1e9值域过大,不能用背......
  • PHP反序列化总结
    0x01.前言本文首发于先知:https://xz.aliyun.com/t/12507。花些时间把四种常见的php反序列化总结了一遍,各自都找了简单示例和例题,参考了一些师傅的链接加上自己的理解,参考链接放在文末0x02.反序列化是什么说到反序列化,经常会想到serialize(),unserialize()这两个函数。我看到......
  • 一维时间序列的离散正交Stockwell变换和离散余弦Stockwell变换
    MATLAB环境下一维时间序列信号的离散正交Stockwell变换和离散余弦Stockwell变换。Stockwell变换是一种对短时傅立叶变换STFT和小波变换WT扩展的时频分析方法。Stockwell变换将傅里叶变换的绝对相位保持特性与WT的频率相关分析和多分辨率特性结合起来。离散正交Stockwell变换......
  • C++动态数组
    #include<iostream>usingnamespacestd;intmain(){ intt,i=0,j=0; cin>>t; char*pc=nullptr;//初始化 int*pi=nullptr;//初始化 float*pf=nullptr;//初始化 intsum=0; intFLAG=0; while(FLAG<t) { charch; cin>>......
  • Chart.js绘制动态折线图
    案例1<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>动态折线图</ti......
  • Python自学☞序列和索引的相关操作
    一、基本概念1、概念序列是一个用于存储多个值的连续空间,每个值都对应一个整数的编号,称为索引2、切片的语法结构注:切片可以访问序列一定范围内的元素序列[start:end:step]    start-->切片的开始索引(包含)    end-->切片的结束索引(不包含)  step-->步长(默......
  • 有效括号序列
    题目描述给出一个仅包含字符’(’,’)’,’{’,’}’,’[‘和’]’,的字符串,判断给出的字符串是否是合法的括号序列,括号必须以正确的顺序关闭,"()"和"()[]{}"都是合法的括号序列,但"(]"和"([)]"不合法。数据范围:字符串长度0≤n≤10000要求:空间复杂度O(n),时间复杂度O(n)......
  • mybatis中常见的动态SQL标签
    在xml中写动态SQL的的时候,有一些常见的,如if、foreachSELECTa.*,c.product_nameFROMwork_orderaLEFTJOINproductcONa.product_code=c.product_codeANDc.del_flag=0wherea.del_flag=0<iftest="orderQueryReq.productCode......
  • [Dubbo] Dubbo 反序列化将Pair转化成HashMap的问题
    问题描述Dubbo在3.2.x版本中,类检查级别默认是STRICT3.1版本中默认为WARN告警级别,3.2版本中默认为STRICT严格检查级别。不配置的情况下,会将名单以外的类型转化成Map。如何支持Pair的序列化和反序列化dubbo.application.serialize-check-status=WARN新建允许的名......