C++ day57 回文子串 最长回文子串序列

题目1:647 回文子串

题目链接:回文子串

对题目的理解

返回字符串s中回文子串的个数,字符串s至少包含一个字符,且仅由小写字母组成。

动态规划

动规五部曲

1)dp数组及下标i的含义

dp[i][j]:[i,j]子串是否为回文子串,代表以s[i]为开头,s[j]为结尾的子串(左闭右闭)

2)递推公式

整体可以分为两种情况,s[i]==s[j]   s[i]!=s[j]

当s[i]等于s[j]时,有3种情况需要考虑:

j==i  两元素重合,代表数组中只有1个元素,那么必是回文子串

j-i==1 两元素相邻,代表数组中有两个元素,且前提是两个元素相等,那么这也必是回文子串

j-i>1 两元素不相邻,但是首尾的两元素相等,仅仅在dp[i+1][j-1]是回文串的基础上,dp[i][j]才是回文串

s[i]!=s[j]时,当前子串一定不是回文串,dp[i][j]=false

3)dp数组初始化

根据dp数组的定义,将其进行初始化,初始化为false,

4)遍历顺序

根据递推公式,从下往上遍历,从左往右遍历

5)打印dp数组

代码

class Solution {
public:
    int countSubstrings(string s) {
        //定义并初始化dp数组
        vector<vector<bool>> dp(s.size(),vector<bool>(s.size(),false));
        int result = 0;
        for(int i=s.size()-1;i>=0;i--){
            for(int j=i;j<=s.size()-1;j++){
                    if(s[i]==s[j]){
                        if(j-i<=1){
                            dp[i][j]=true;
                            result++;
                        }
                        else if(dp[i+1][j-1]==true){
                            dp[i][j]=true;
                            result++;
                        }
                    }
            }
        }
        return result;
    }
};
  • 时间复杂度:O(n^2)
  • 空间复杂度:O(n^2)

代码流程

法2:双指针法

首先确定回文串,就是找中心然后向两边扩散看是不是对称的就可以了。

在遍历中心点的时候,要注意中心点有两种情况:

1)一个元素可以作为中心点;

2)两个元素也可以作为中心点。

三个元素就可以由一个元素左右添加元素得到,四个元素则可以由两个元素左右添加元素得到,以此类推,因此,只分析一个元素作为中心点和两个元素作为中心点就可以了

代码

class Solution {
public:
    int extend(string& s,int i,int j,int n){
        int res;
        while(i>=0 && j<n && s[i]==s[j]){
            i--;
            j++;
            res++;
        }
        return res;
    }
    int countSubstrings(string s) {
        int result = 0;
        for(int i=0;i<s.size();i++){
            result += extend(s,i,i,s.size());
            result += extend(s,i,i+1,s.size());
        }
        return result;
    }
};

以上代码对于案例会计算错误,如图,原因就是未对res进行初始化

注意一定要对res进行初始化,不然会报以上错误,将代码修改为如下,就能够运行了

class Solution {
public:
    int extend(string& s,int i,int j,int n){
        int res=0;
        while(i>=0 && j<n && s[i]==s[j]){
            i--;
            j++;
            res++;
        }
        return res;
    }
    int countSubstrings(string s) {
        int result = 0;
        for(int i=0;i<s.size();i++){
            result += extend(s,i,i,s.size());
            result += extend(s,i,i+1,s.size());
        }
        return result;
    }
};
  • 时间复杂度:O(n^2)
  • 空间复杂度:O(1)

代码流程

题目2:516 最长回文子序列

题目链接:最长回文子序列

对题目的理解

返回字符串s中最长回文子序列的长度,字符串s至少包含一个字符,且仅由小写字母组成。

动态规划

动规五部曲

1)dp数组及下标i的含义

 dp[i][j]:[i,j]范围内的回文子序列的长度(左闭右闭)

2)递推公式

分为两种情况,s[i]==s[j]   s[i]!=s[j]

当s[i]==s[j]时,dp[i][j]=dp[i+1][j-1]+2,加2是因为s[i]与s[j]相等,在原来回文子序列长度dp[i+1][j-1]的基础上加上2(这两个元素相同)

s[i]!=s[j]时,说明s[i]和s[j]的同时加入并不能增加[i,j]区间回文子序列的长度,那么分别加入s[i]、s[j]看看哪一个可以组成最长的回文子序列,因此要分为两种情况,考虑s[i]而不考虑s[j]   考虑s[j]而不考虑s[i]

1)考虑s[i]而不考虑s[j]   dp[i][j]=dp[i][j-1]

2)考虑s[j]而不考虑s[i-1]  dp[i][j]=dp[i+1][j]

dp[i][j]=max(dp[i][j-1],dp[i+1][j])

3)dp数组初始化

首先要考虑当i 和j 相同的情况,从递推公式:dp[i][j] = dp[i + 1][j - 1] + 2; 可以看出 递推公式是计算不到 i 和j相同时候的情况,因为本题求的是最长回文子序列的长度,所以需要手动初始化一下,当i与j相同,那么dp[i][j]一定是等于1的,即:一个字符的回文子序列长度就是1

根据递推公式,i一直加1,j一直减1,直到i==j

i==j时是初始化位置,指向了一个元素,一定是回文的,即dp[i][i]=1

!!!其他情况dp[i][j]初始为0就行,这样递推公式:dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]); 中dp[i][j]才不会被初始值覆盖,一定要初始化为0,这样才不会被覆盖

4)遍历顺序

根据递推公式,dp[i][j] 依赖于 dp[i + 1][j - 1] ,dp[i + 1][j] 和 dp[i][j - 1],从下往上遍历,从左往右遍历,这两个for循环不可以颠倒,因为j依赖于i,因为字符串的范围是[i,j],j一定是大于等于i的,一定是i在前,j在后。

5)打印dp数组

最终结果是dp[0][s.size()-1]   

代码

class Solution {
public:
    int longestPalindromeSubseq(string s) {
        //定义dp数组
        vector<vector<int>> dp(s.size(),vector<int>(s.size(),0));
        //初始化dp数组
        for(int i=0;i<s.size();i++) dp[i][i]=1;
        for(int i=s.size()-1;i>=0;i--){
            for(int j=i+1;j<s.size();j++){
                if(s[i]==s[j]) dp[i][j]=dp[i+1][j-1]+2;
                else dp[i][j]=max(dp[i+1][j],dp[i][j-1]);
            }
        }
        return dp[0][s.size()-1];
    }
};
  • 时间复杂度: O(n^2)
  • 空间复杂度: O(n^2)

代码流程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/227731.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

22款奔驰S450L升级主动式环境氛围灯 安全提醒功能

主动式氛围灯有263个可多色渐变的LED光源&#xff0c;营造出全情沉浸的动态光影氛围。结合智能驾驶辅助系统&#xff0c;可在转向或检测到危险时&#xff0c;予以红色环境光提示&#xff0c;令光影艺术彰显智能魅力。配件有6个氛围灯&#xff0c;1个电脑模块。星骏汇小许Xjh158…

第二十一章——网络通信总结

网络程序设计基础 局域网与互联网 为了实现两台计算机的通信&#xff0c;必须用一个网络线路连接两台计算机。如下图所示 网络协议 1.IP协议 IP是Internet Protocol的简称&#xff0c;是一种网络协议。Internet 网络采用的协议是TCP/IP协议&#xff0c;其全称是Transmission…

第21章网络通信

Internet 提供了大量有用的信息&#xff0c;很少有人能在接触过Internet后拒绝它的诱惑。计算机网络实现了多台计算机间的互联&#xff0c;使得它们彼此之间能够进行数据交流。网络应用程序就是在已连接的不同计算机上运行的程序&#xff0c;这些程序借助于网络协议&#xff0c…

Python编程技巧 – 异常处理

Python编程技巧 – 异常处理 Python Programming Skills – Exception Handling By JacksonML 每一个程序都未必是健壮的&#xff0c;有时候很脆弱。只有在人的理想思维状况下&#xff0c;返回的结果才是正确的&#xff0c;如意的。 1. 错误发生及异常输出 面对种种编写有疏…

【mysql】下一行减去上一行数据、自增序列场景应用

背景 想获取if_yc为1连续账期数据 思路 获取所有if_yc为1的账期数据下一行减去上一行账期&#xff0c;如果为1则为连续&#xff0c;不等于1就为断档获取不等于1的最小账期&#xff0c;就是离当前账期最近连续账期 代码 以下为mysql语法&#xff1a; select acct_month f…

机场信息集成系统系列介绍(1)

机场信息集成系统是一种专为机场运营管理设计的先进系统&#xff0c;旨在提高机场的航班调度指挥效率&#xff0c;同时为机场各生产部门提供航班保障计划的制定和实时调整功能。 该系统的核心用户是机场运控部门&#xff0c;他们利用系统进行航班运行指挥&#xff0c;通过采集航…

Kafka性能调优:高吞吐、低延迟的数据流

Apache Kafka作为一种高性能、分布式流处理平台&#xff0c;对于实时数据的处理至关重要。本文将深入讨论Kafka性能调优的关键策略和技术&#xff0c;通过丰富的示例代码为大家提供实际操作指南&#xff0c;以构建高吞吐、低延迟的数据流系统。 Broker 配置的优化 首先&#…

中断、异常和系统调用(2-1,2-2,2-3)

2-1 课堂练习2.1&#xff1a;外部中断 本实训分析 Linux 0.11 对外部中断的响应和处理过程。在每条指令执行的末尾&#xff0c;如果没有关中断&#xff0c;CPU 会检查是否收到了外部中断信号&#xff0c;如果有信号&#xff0c;则 CPU 就切换到核心态去执行对应的中断处理程序…

c# 字段和属性(get、set、init)

基本概念&#xff1a; “字段”就是类内成员变量&#xff0c;一般为了隐藏数据&#xff0c;保护数据&#xff0c;实现对外不可见&#xff0c;体现封装的思想&#xff0c;成员变量都声明为私有变量&#xff1b;“属性”是类内的一种成员&#xff0c;它是一种特殊的方法(方法的意…

文件被删除了怎么恢复?3个宝藏方法,快来get!

“我是一个学生党&#xff0c;期末的一些资料保存在电脑上&#xff0c;但是不知道是不是被我误删了&#xff0c;导致很多文件都找不到了。文件被删除了怎么恢复呢&#xff1f;大家帮我出出主意吧&#xff01;” 对于经常在电脑上保存各种文件的用户来说&#xff0c;文件误删除是…

万宾科技荣获2023物联网场景应用品牌企业创始人发表专题演讲

12月5日-6日由雄安新区管理委员会、中关村发展集团股份、物联中国团体组织联席会主办&#xff0c;全国33家物联网协会协办的2023物联网产业品牌大会于在雄安新区顺利召开。本次大会以“物联中国.数智雄安”为主题&#xff0c;邀请到科技部原副部长吴忠泽&#xff0c;雄安新区管…

MIT线性代数笔记-第25讲-复习二

目录 25.复习二打赏 25.复习二 已知 a ⃗ [ 2 1 2 ] \vec{a} \begin{bmatrix} 2 \\ 1 \\ 2 \end{bmatrix} a ​212​ ​&#xff0c;求&#xff1a; (1) a ⃗ \vec{a} a 的投影矩阵 (2) a ⃗ \vec{a} a 的投影矩阵的特征值和特征向量 A n s Ans Ans&#xff1a;(1) P a ⃗…

【面试】Java最新面试题资深开发-JVM第二弹

问题三&#xff1a;JVM 内存为什么要分成新生代&#xff0c;老年代&#xff0c;持久代。新生代中为什么要分为 Eden 和 Survivor 为什么要分成新生代和老年代&#xff1a; 对象生命周期假设&#xff1a; 大多数对象在被创建后很短时间内就会变成垃圾。通过将这些短命的对象放入…

代码混淆技术探究与工具选择

代码混淆技术探究与工具选择 引言 在软件开发中&#xff0c;保护程序代码的安全性是至关重要的一环。代码混淆&#xff08;Obfuscated code&#xff09;作为一种常见的保护手段&#xff0c;通过将代码转换成难以理解的形式来提升应用被逆向破解的难度。本文将介绍代码混淆的概…

vue2+datav可视化数据大屏(2)

接上一节所说 我们已经讲骨架搭好 这节我们讲述的如何在vue2中使用mock数据和封装axios 1&#xff0c;项目中使用moke &#x1f4d3;什么是mock&#xff1f;&#xff0c;mock就是假数据&#xff0c;除了数据是假的&#xff0c;其他内容都和正常工作中后端开发的接口都是一致的…

3.PyTorch——常用神经网络层

import numpy as np import pandas as pd import torch as t from PIL import Image from torchvision.transforms import ToTensor, ToPILImaget.__version__2.1.13.1 图像相关层 图像相关层主要包括卷积层&#xff08;Conv&#xff09;、池化层&#xff08;Pool&#xff09;…

KP 2sv Authenticator一款免费处理亚马逊两步验证码的软件

KP 2sv Authenticator 被誉为一款免费而强大的亚马逊两步验证软件&#xff0c;操作简便轻松。 软件使用方法极为简单&#xff0c;用户只需直接输入身份验证应用程序生成的代码&#xff0c;即可迅速生成随机验证码&#xff0c;帮助用户顺利完成亚马逊的两步验证流程。这款小软件…

dockers安装rabbitmq

RabbitMQ: easy to use, flexible messaging and streaming — RabbitMQhttps://www.rabbitmq.com/ Downloading and Installing RabbitMQ — RabbitMQ docker run -it --rm --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3.12-management 之后参照&#xff1a;dock…

基于个微机器人的开发

简要描述&#xff1a; 下载消息中的动图 请求URL&#xff1a; http://域名/getMsgEmoji 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 参数&#xff1a; 参数名必选类型说明…

【EXCEL】折线图添加垂直x轴的竖线|画图

相关链接&#xff1a;excel 添加垂直竖向直线 如何在Excel中添加水平和垂直线&#xff1f; 因为加辅助列有点不习惯&#xff0c;已经有分位数横坐标了&#xff0c;想着试下用散点图的误差线画 效果图&#xff1a; 步骤&#xff1a; s1&#xff1a;随便框选两列数据–>插入(…
最新文章