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

力扣第647题 回文子串 c++ 动态规划 双指针 附Java代码 注释解释版

题目

647. 回文子串

中等

相关标签

字符串   动态规划

给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。

回文字符串 是正着读和倒过来读一样的字符串。

子字符串 是字符串中的由连续字符组成的一个序列。

具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。

示例 1:

输入:s = "abc"
输出:3
解释:三个回文子串: "a", "b", "c"

示例 2:

输入:s = "aaa"
输出:6
解释:6个回文子串: "a", "a", "a", "aa", "aa", "aaa"

提示:

  • 1 <= s.length <= 1000
  • s 由小写英文字母组成

思路和解题方法 一 动态规划

  1. vector<vector<bool>> dp(s.size(),vector<bool>(s.size(),false));:这行代码定义了一个二维布尔类型的动态规划数组dp,用来记录字符串s中从位置i到j的子串是否为回文串。

  2. int ans = 0;:初始化一个变量ans用来存储回文子串的数量。

  3. for(int i = s.size()-1;i>=0;i--):从字符串的末尾向前遍历每个字符,作为子串的起始位置。

  4. for(int j = i;j<s.size();j++):遍历以当前i位置字符为起始的所有可能的子串。

  5. if(s[i] == s[j] && (j-i<=1||dp[i+1][j-1])):如果当前子串的两端字符相同,并且长度不超过1,或者去掉两端字符后剩下的子串是回文串(根据dp数组的记录),则认为当前子串是回文串。

  6. ans++;:累加回文子串的数量。

  7. dp[i][j] = true;:更新dp数组,表示从位置i到j的子串是回文串。

  8. 最后返回ans,即为字符串s中回文子串的数量。

复杂度

        时间复杂度:

                O(n*n)

        时间复杂度为O(n^2),其中n为输入字符串s的长度。这是因为代码中使用了两重循环来遍历所有可能的子串,并在每次循环中进行常数时间的比较和更新操作。

        空间复杂度

                O(n*n)

        至于空间复杂度,由于使用了一个二维动态规划数组dp,其大小为s.size() * s.size(),因此空间复杂度也为O(n^2)。

c++ 代码 1

打印的dp数组:(以“abcba"为样例)

  a  b  c   b  a

class Solution {
public:int countSubstrings(string s) {// 创建一个二维动态规划数组dp,用于记录子串是否为回文vector<vector<bool>> dp(s.size(), vector<bool>(s.size(), false));int ans = 0; // 记录回文子串的数量for (int i = s.size() - 1; i >= 0; i--) {for (int j = i; j < s.size(); j++) {// 如果当前字符相等,并且满足回文条件,则更新结果和dp数组if (s[i] == s[j] && (j - i <= 1 || dp[i + 1][j - 1])) {ans++; // 回文子串数量加一dp[i][j] = true; // 更新dp数组表示从i到j的子串是回文}}}return ans; // 返回回文子串的数量}
};

双指针

先看时间空间复杂度对比:(大差不差的区别)

以下是双指针法

思路和解题方法 二 双指针

  1. 主函数countSubstrings中,首先初始化变量ans为0,用于存储回文子串的数量。

  2. 然后通过一个for循环遍历字符串s的每个字符(下标为i),对于每个字符,分别调用explore函数两次:

    • 第一次调用explore(s, i, i, s.size()):以当前字符为中心,向两边扩展寻找回文子串。
    • 第二次调用explore(s, i, i+1, s.size()):以当前字符和下一个字符为中心,向两边扩展寻找回文子串。
  3. explore函数中,通过双指针i和j向两边扩展,检查以i和j为中心的回文子串数量。

  4. 当i和j位置的字符相等时,i向左移动,j向右移动,并同时增加回文子串数量cnt

  5. 最后返回cnt作为以i和j为中心的回文子串数量。

  6. 最后,主函数返回累加的回文子串数量ans

复杂度

        时间复杂度:

                O(n*n)

       时间复杂度为O(n^2),其中n为输入字符串s的长度。这是因为在主函数countSubstrings中,通过一个嵌套的循环遍历字符串s的每个字符,并且在explore函数中,利用双指针向两边扩展来判断回文子串,最坏情况下需要O(n)的时间复杂度。

        空间复杂度

                O(1)

        空间复杂度则为O(1),因为除了存储回文子串数量的变量ans外,算法并未使用额外的空间,因此空间复杂度是常数级的。

c++ 代码 2

class Solution {
public:int countSubstrings(string s) {int ans = 0; // 初始化回文子串数量为0for(int i = 0; i < s.size(); i++) { // 遍历字符串s的每个字符ans += explore(s, i, i, s.size()); // 以当前字符为中心,向两边扩展寻找回文子串ans += explore(s, i, i + 1, s.size()); // 以当前字符和下一个字符为中心,向两边扩展寻找回文子串}return ans; // 返回回文子串的总数量}int explore(const string &s, int i, int j, int n) {int cnt = 0; // 记录以i和j为中心的回文子串数量while(i >= 0 && j < n && s[i] == s[j]) { // 向两边扩展,直到不是回文串为止i--; // 向左移动指针j++; // 向右移动指针cnt++; // 回文子串数量加一}return cnt; // 返回回文子串数量}
};

附Java代码

1.动态规划

class Solution {public int countSubstrings(String s) {// 创建一个二维数组dp,dp[i][j]表示从索引i到索引j的子串是否为回文子串boolean[][] dp = new boolean[s.length()][s.length()];int res = 0; // 用于存储回文子串数量的变量// 双重循环遍历字符串,i表示起始索引,j表示结束索引for (int i = s.length() - 1; i >= 0; i--) {for (int j = i; j < s.length(); j++) {// 如果当前字符相等,并且满足以下条件之一:// 1. j和i相差不超过1,即长度为1或2的子串// 2. dp[i+1][j-1]为true,即去掉头尾字符后的子串是回文串if (s.charAt(i) == s.charAt(j) && (j - i <= 1 || dp[i + 1][j - 1])) {res++; // 回文子串数量加1dp[i][j] = true; // 标记索引i到索引j的子串为回文子串}}}return res; // 返回回文子串数量}
}

2.双指针

class Solution {public int countSubstrings(String s) {int len, ans = 0; // 初始化变量len和ansif (s == null || (len = s.length()) < 1) return 0; // 如果输入字符串为空或长度小于1,则直接返回0// 总共有2 * len - 1个中心点,因为可以以每个字符为中心,也可以以两个字符之间的空隙为中心for (int i = 0; i < 2 * len - 1; i++) {// 通过遍历每个回文中心,向两边扩散,并判断是否回文子串// 有两种情况,当i为偶数时,回文中心是一个字符;当i为奇数时,回文中心是两个字符之间的空隙int left = i / 2, right = left + i % 2; // 根据i的奇偶性确定回文中心的左右位置while (left >= 0 && right < len && s.charAt(left) == s.charAt(right)) {// 如果当前是一个回文子串,则记录数量ans++;left--;right++;}}return ans; // 返回回文子串数量}
}

觉得有用的话可以点点赞,支持一下。

如果愿意的话关注一下。会对你有更多的帮助。

每天都会不定时更新哦  >人<  。

相关文章:

力扣第647题 回文子串 c++ 动态规划 双指针 附Java代码 注释解释版

题目 647. 回文子串 中等 相关标签 字符串 动态规划 给你一个字符串 s &#xff0c;请你统计并返回这个字符串中 回文子串 的数目。 回文字符串 是正着读和倒过来读一样的字符串。 子字符串 是字符串中的由连续字符组成的一个序列。 具有不同开始位置或结束位置的子串…...

【Go入门】struct类型

【Go入门】struct类型 struct Go语言中&#xff0c;也和C或者其他语言一样&#xff0c;我们可以声明新的类型&#xff0c;作为其它类型的属性或字段的容器。例如&#xff0c;我们可以创建一个自定义类型person代表一个人的实体。这个实体拥有属性&#xff1a;姓名和年龄。这样…...

怎么改变容易紧张的性格?

容易紧张的性格是比较通俗的说法&#xff0c;在艾森克人格测试中&#xff0c;容易紧张的性格就属于神经症人格&#xff0c;神经质不是神-经-病&#xff0c;而是一种人格特征&#xff0c;这种特征包括&#xff1a;敏感&#xff0c;情绪不稳定&#xff0c;易焦虑和紧张。有兴趣的…...

合作共赢 共克时艰

​ 采访人&#xff1a;最近财政部11月6日通报隐性债务问责典型案例&#xff0c;这中间涉及湖北多所重要地市&#xff0c;形成新增隐性债务200多亿&#xff0c;您怎么看这件事&#xff1f; 辜渝傧&#xff1a;是的&#xff0c;无论是数字还是涉及的范围都可以明显感觉到“防范…...

VCSA7许可证过期问题

公司两台ESXI7虚拟化系统&#xff0c;使用VCSA7进行日常管理&#xff0c;在使用过程中一直清单中包含过期或即将过期的许可证。 查看许可证清单中&#xff0c;已经添加了正式授权的许可证&#xff0c;且已经分配给了ESXI主机&#xff0c;但是任然有到期提示。 最后查看试用许可…...

解决win11更新后,文件夹打不开的bug

更新win11系统了&#xff0c;给我更了个bug&#xff0c;找了好多解决方案&#xff0c;发现下面这个可以解决问题。 第一步 找到注册表 第二步 备份注册表 为了防止意外情况&#xff0c;备份注册表。如有意外问题&#xff0c;可以导入导出的注册表进行恢复。 第三步 删除指定…...

修复了数个Bug!

v2.0.1版本已经在 github release 了&#xff0c;欢迎大家体验使用&#xff0c;开源版是永久免费的。 ## 新增与优化的功能 新增(测试报告): 测试报告根据测试执行详情&#xff0c;进行查看 新增(用户设置): 用户权限为普通用户和管理员&#xff0c;普通用户根据设置的默认产品…...

设计模式之--原型模式(深浅拷贝)

原型模式 缘起 某天&#xff0c;小明的Leader找到小明:“小明啊&#xff0c;如果有个发简历的需求&#xff0c;就是有个简历的模板&#xff0c;然后打印很多份&#xff0c;要去一份一份展示出来&#xff0c;用编程怎么实现呢&#xff1f;” 小明一听&#xff0c;脑袋里就有了…...

Linux服务器从零开始训练 RT-DETR 改进项目 (Ultralytics) 教程,改进RTDETR算法(包括使用训练、验证、推理教程)

手把手从零开始训练 RT-DETR 改进项目 (Ultralytics版本) 教程,改进RTDETR算法 本文以Linux服务器为例:从零开始使用Linux训练 RT-DETR 算法项目 《芒果剑指 RT-DETR 目标检测算法 改进》 适用于芒果专栏改进RT-DETR算法 文章目录 百度 RT-DETR 算法介绍改进网络代码汇总第…...

矩阵理论--矩阵分解

矩阵理论–矩阵分解 矩阵的三角分解、谱分解、最大秩分解、奇异值分解的操作步骤&#xff0c;以及相关说明。 1、QR分解 &#xff08;1&#xff09;非奇异方阵 方阵&#xff08;非奇异&#xff09;&#xff1a;将方阵分解成酉矩阵左乘正线上三角&#xff0c;或者酉矩阵右乘…...

go语言相关bug

第一个bug itcastitcast:/home/jian/share/src/go-test/homeweb-client$ go mod tidy go: finding module for package github.com/micro/go-grpc go: found github.com/micro/go-grpc in github.com/micro/go-grpc v1.0.1 go: homeweb-client/handler importsgithub.com/micr…...

Spring Cloud OpenFeign:基于Ribbon和Hystrix的声明式服务调用

&#x1f497;wei_shuo的个人主页 &#x1f4ab;wei_shuo的学习社区 &#x1f310;Hello World &#xff01; Spring Cloud OpenFeign&#xff1a;基于Ribbon和Hystrix的声明式服务调用 Spring Cloud OpenFeign是一个声明式的服务调用框架&#xff0c;基于Feign并整合了Ribbon和…...

租用服务器带宽类型应用

服务器带宽类型多样&#xff0c;以满足不同行业的需求。本文将介绍香港常见的服务器带宽类型及其应用领域。 1. 共享带宽 共享带宽是指多个用户共同使用同一台服务器的带宽资源。这种带宽类型适用于小型企业或个人网站&#xff0c;因为其成本较低。由于多个用户共享带宽资源&…...

SOLIDWORKS实用技巧之焊件轮廓应用

1.焊件轮廓库官方下载入口 焊件轮廓可以自制&#xff0c;也可以从软件中在线下载获取直接使用&#xff0c;如图1&#xff0c;联网状态按ctrl左键点击下载&#xff0c;解压后获得库文件。 图1 图2 2.库放置的位置和配置 从SOLIDWORKS2014版起&#xff0c;软件焊件轮廓库支持可…...

本地浏览器全局翻译 demo 以火狐firefox为例【免费-简单】

translateDemo 介绍使用说明简单到流泪 本地浏览器全局翻译 demo 以火狐firefox为例 1、安装插件 使用少量的 JavaScript 脚本&#xff0c;自由定义网页显示与运行方式。2、将上述脚本 追加到 插件中即可实现全局翻译&#xff1b;3、免费&#xff1b;参与贡献特技 translateDe…...

使用多线程处理List数据

最近遇到了一个业务场景&#xff0c;需要对List中的数据逐个发起http请求(List中的数据各自独立&#xff0c;对执行顺序无要求)&#xff0c;考虑到可以使用多线程加快处理速度。 封装了如下方法&#xff1a; /// <summary>/// 多线程处理数据-无返回值/// </summary&…...

Elasticsearch--Python使用、Django/Flask集成

一、Python使用 from elasticsearch import Elasticsearchobj Elasticsearch() # 创建索引&#xff08;Index&#xff09; result obj.indices.create(indexuser, body{"userid":1,username:lqz},ignore400) # print(result) # 删除索引 # result obj.indices.de…...

pyspark将数据多次插入表的时候报错

代码 报错信息 py4j.protocol.Py4JJavaError: An error occurred while calling o129.sql. : org.apache.spark.sql.catalyst.parser.ParseException: mismatched input INSERT expecting <EOF>(line 12, pos 0) 原因 插入语句结束后没有加&#xff1b;结尾 把两个&am…...

Qt绘制饼状图

必须在MainWindow.h头文件开头放 #include <QtCharts> //必须这么设置 创建chart&#xff1a; void MainWindow::iniPiewChart() { //饼图初始化QChart *chart new QChart();chart->setTitle(" Piechart演示");chart->setAnimationOptions(QChar…...

Vue3 setup函数

一、setup函数介绍 setup函数是Vue3中全新的一个配置项&#xff0c;值为一个函数&#xff0c;是所有 Composition API 中“表演的舞台”。 我们在Vue2中用到的所有数据、方法&#xff0c;都需要配置在setup中。 这是我们在Vue2中的写法&#xff1a; 这是我们在Vue3 setup中的…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer &#xff08;1&#xff09;资源 论文&a…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

C++:多态机制详解

目录 一. 多态的概念 1.静态多态&#xff08;编译时多态&#xff09; 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1&#xff09;.协变 2&#xff09;.析构函数的重写 5.override 和 final关键字 1&#…...

【网络安全】开源系统getshell漏洞挖掘

审计过程&#xff1a; 在入口文件admin/index.php中&#xff1a; 用户可以通过m,c,a等参数控制加载的文件和方法&#xff0c;在app/system/entrance.php中存在重点代码&#xff1a; 当M_TYPE system并且M_MODULE include时&#xff0c;会设置常量PATH_OWN_FILE为PATH_APP.M_T…...