代码随想录算法训练营第六十天_第九章_动态规划 | 647. 回文子串、516.最长回文子序列、动态规划总结篇

news2025/1/19 17:16:26

LeetCode 647. 回文子串

        给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。

视频讲解https://www.bilibili.com/video/BV17G4y1y7z9/?spm_id_from=333.788&vd_source=f98f2942b3c4cafea8907a325fc56a48文章讲解https://programmercarl.com/0647.%E5%9B%9E%E6%96%87%E5%AD%90%E4%B8%B2.html

⭐如果s[i + 1, j - 1]是回文子串 且 s[i] == s[j] 👉s[i, j]是回文子串

  • 思路:
    • 思路一,动态规划:
      • dp数组含义:bool类型 dp[i][j] 表示 子串[i, j]是否回文
      • 递推公式:只用维护 i <= j 的 dp[i][j],考虑以下情况
        • 情况一:i == j,例如"a",true
        • 情况二:i + 1 == j,例如"aa",true
        • 情况三:i + 1 < j,看dp[i + 1][j - 1](此时dp[i + 1][j - 1]才有意义)
      • 初始化:全false
      • 遍历顺序:从下到上/从左到右
    • 思路二,双指针:
      • 遍历s,取中心点用于向两边对称位置扩展
        • 以 i 为中心(奇数)
        • 以 i 和 i + 1 为中心(偶数)
      • 从中心向两边比较,统计回文子串的数目
  • 代码:
// 思路一,动态规划:
class Solution {
public:
    int countSubstrings(string s) {
        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(); j++) {
                if (s[i] == s[j]) {
                    if (j - i <= 1) { // 情况一 和 情况二
                        result++;
                        dp[i][j] = true;
                    } else if (dp[i + 1][j - 1]) { // 情况三
                        result++;
                        dp[i][j] = true;
                    }
                }
            }
        }
        return result;
    }
};

// 简洁版:
class Solution {
public:
    int countSubstrings(string s) {
        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(); j++) {
                if (s[i] == s[j] && (j - i <= 1 || dp[i + 1][j - 1])) {
                    result++;
                    dp[i][j] = true;
                }
            }
        }
        return result;
    }
};
// 时间复杂度:O(n^2)
// 空间复杂度:O(n^2)
// 思路二,双指针:
class Solution {
public:
    int countSubstrings(string s) {
        int result = 0;
        for (int i = 0; i < s.size(); i++) {
            result += extend(s, i, i, s.size()); // 以i为中心
            result += extend(s, i, i + 1, s.size()); // 以i和i+1为中心
        }
        return result;
    }
    int extend(const 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;
    }
};
// 时间复杂度:O(n^2)
// 空间复杂度:O(1)

LeetCode 516.最长回文子序列

        给定一个字符串 s ,找到其中最长的回文子序列,并返回该序列的长度。可以假设 s 的最大长度为 1000 。

视频讲解https://www.bilibili.com/video/BV1d8411K7W6/?spm_id_from=333.788&vd_source=f98f2942b3c4cafea8907a325fc56a48文章讲解https://programmercarl.com/0516.%E6%9C%80%E9%95%BF%E5%9B%9E%E6%96%87%E5%AD%90%E5%BA%8F%E5%88%97.html

  • 思路:
    • dp数组含义:dp[i][j] 表示 子串[i, j]的最长回文子序列的长度
    • 递推公式:
      • s[i] 与 s[j] 相同👉dp[i][j] = dp[i + 1][j - 1] + 2;
      • s[i] 与 s[j] 不同👉dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);

    • 初始化dp[i][i] = 1;其余全0
    • 遍历顺序:从下到上,从左到右
    • 最终结果:dp[0][s.size() - 1]; 
  • 代码:
class Solution {
public:
    int longestPalindromeSubseq(string s) {
        vector<vector<int>> dp(s.size(), vector<int>(s.size(), 0));
        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];
    }
};

动态规划总结篇

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux 进程知识总结

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&#xff1a;Linux操作…

高阶数据结构之哈希的应用

文章目录位图&#xff08;bitMap&#xff09;位图的实现将数据添加到位图中检查数据是否在位图中存在将数据的对应位置置为0位图的应用布隆过滤器为什么会有误差布隆过滤器的实现布隆过滤器的删除使用Google下的guava组件操作布隆过滤器布隆过滤器的缺陷布隆过滤器的使用场景海…

分享69个ASP源码,总有一款适合您

分享69个ASP源码&#xff0c;总有一款适合您 69个ASP源码下载链接&#xff1a;https://pan.baidu.com/s/1XXwBL0Y0nOSel9xJVqz0Ow?pwdertw 提取码&#xff1a;ertw Python采集代码下载链接&#xff1a;https://wwgn.lanzoul.com/iKGwb0kye3wj base_url "https://d…

关于JavaScript编译原理以及作用域的深入探讨

前言 几乎所有编程语言最基本的功能之一&#xff0c;就是能够储存变量当中的值&#xff0c;并且能在之后对这个值进行访问或修改。事实上&#xff0c;正是这种储存和访问变量的值的能力将状态带给了程序。 若没有了状态这个概念&#xff0c;程序虽然也能够执行一些简单的任务…

高码率QPSK调制解调方案(2.1 QPSK调制)

2 全数字高码率QPSK调制解调软件设计 2.1 QPSK调制 2.1.1 QPSK调制原理 QPSK调制即正交相移键控信号,其信号表达式为 (1) 其中,和分别表示每比特的能量和持续

​LabView​动态改变显示文本框的属性(颜色、字体)

目录 问题&#xff1a; 解决方式 1、在程序框图面板上&#xff0c;选择显示文本框&#xff0c;右键创建属性节点 2、选择属性节点为数值文本&#xff0c;依据需要改变的类型选择文本颜色或字体 3、依据下位机上传的数值大小&#xff0c;选择-条件结构类型&#xff0c;依据…

03俯瞰全局:gRPC是如何进行通信的

gRPC作为Web网站和APP后端的最常用服务提供方式之一和分布式微服务架构不同节点间的最常见通信方式之一,它自身是如何进行通信的呢,这个问题就是我们本篇文章将要研究的重点,先从全局的角度分析gRPC服务端和客户端进行通信的主要流程,再从细节剖析gRPC是如何进行高效的远程…

Qt QVector “isDetached()“

文章目录摘要尝试通过加锁解决lock&unlockQMutexLockertry_lock改变量属性Q_ASSERT参考关键字&#xff1a; ASSERT、 isDetached、 崩溃、 QVector、 Detach摘要 今天在公司填坑的时候&#xff0c;有随机获得了一个新的BUG&#xff0c;就是一直报ASSERT&#xff1a;”isD…

剑指 Offer 35. 复杂链表的复制

题目 请实现 copyRandomList 函数&#xff0c;复制一个复杂链表。在复杂链表中&#xff0c;每个节点除了有一个 next 指针指向下一个节点&#xff0c;还有一个 random 指针指向链表中的任意节点或者 null。 思路 方法一&#xff1a;哈希表 利用哈希表的查询特点&#xff…

【Linux】项目自动化构建工具-make/Makefile与Linux调试器-gdb使用

文章目录Linux项目自动化构建工具-make/MakefileLinux调试器-gdb使用Linux项目自动化构建工具-make/Makefile 背景 会不会写makefile&#xff0c;从一个侧面说明了一个人是否具备完成大型工程的能力一个工程中的源文件不计数&#xff0c;其按类型、功能、模块分别放在若干个目录…

SpringBoot+Vue图书馆管理系统

简介&#xff1a;本项目采用了基本的SpringBootVue设计的图书馆管理系统。详情请看截图。经测试&#xff0c;本项目正常运行。本项目适用于Java毕业设计、课程设计学习参考等用途。 项目描述 项目名称SpringBootVue图书馆管理系统源码作者LHL项目类型Java EE项目 &#xff08;…

【iMessage苹果推推送】将看到一个可扩大选项“AppleDevelopmentPushServices”6.扩展此选项并右键单击“Appledge”>

推荐内容IMESSGAE相关 作者✈️IMEAX推荐内容iMessage苹果推软件 *** 点击即可查看作者要求内容信息作者✈️IMEAX推荐内容1.家庭推内容 *** 点击即可查看作者要求内容信息作者✈️IMEAX推荐内容2.相册推 *** 点击即可查看作者要求内容信息作者✈️IMEAX推荐内容3.日历推 *** …

基于NOSTR协议的“公有制”版本的Twitter,去中心化社交软件Damus用后感,一个极端走向另一个极端

最近&#xff0c;一个幽灵&#xff0c;Web3的幽灵&#xff0c;在网络游荡&#xff0c;它叫Damus&#xff0c;这玩意诠释了什么叫做病毒式营销&#xff0c;滑稽的是&#xff0c;一个Web3产品却在Web2的产品链上疯狂传销&#xff0c;各方大佬纷纷为其背书&#xff0c;到底发生了什…

基于python实现疫情期间微博、B站网民情绪分析

一项目概述&#xff1a;“疫情下的社会心理学”这一课题旨在通过疫情期间大众在自媒体上的新闻评论等信息&#xff0c;凭借一些方法分析出总体的心理变化和情绪走向&#xff0c;并在宏观上把握了总体的心态格局。对于该课题&#xff0c;我们小组首先爬取了哔哩哔哩和微博的大量…

Spring Boot(三):第二种导入依赖方式的实战案例(常用)

文章目录 第二种导入依赖方式的实战案例 一、导入依赖方式1&#xff08;拓展方法&#xff09; 二、使用idea自带springBoot项目初始化插件 第二种导入依赖方式的实战案例 一、导入依赖方式1&#xff08;拓展方法&#xff09; 在公司中可能会出现必须继承某个项目&#xff…

Linux日志分析工具之AWStats

Linux日志分析工具之AWStats &#x1f4d2;博客主页&#xff1a; 微笑的段嘉许博客主页 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐留言&#x1f4dd; &#x1f4cc;本文由微笑的段嘉许原创&#xff01; &#x1f4c6;CSDN首发时间&#xff1a;&#x1f334;2…

力扣sql简单篇练习(十)

力扣sql简单篇练习(十) 1 过去30天的用户活动 || 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 a 示例输入 b 示例输出 1.2 示例sql语句 # 多少天内使用Date_SUB函数,具体用法是Date_SUB(初始日期,interval 变更的天数 day) ,正数找过去负数找未来 # 变更天数多少…

接口测试、接口协议以及常用接口测试工具介绍

目录 一、前言&#xff1a;什么是接口 二、接口协议以及对应的接口测试工具 三、接口测试如何设计测试用例&#xff1f; 四、接口组成&#xff1f; 五、总结 一、前言&#xff1a;什么是接口 1.接口指的是软件提供给外界的一种服务。作用在于使其内部的数据能被外部进行修…

买的香港云服务器怎么用?云服务器使用教程

香港云服务器的优势及好处&#xff0c;使得很多人都愿意使用和推荐&#xff0c;推荐的人多了自然购买的人就多了&#xff0c;其中不乏很大部分新手&#xff0c;购买之后却不知道该怎么使用和管理登录等操作。下面我们聊聊香港云服务器怎么登录使用。 香港云服务器登录管理方法&…

论文浅尝 | 基于无监督标注的漏洞描述文本概念抽取

笔记整理&#xff1a;韩林峄&#xff0c;天津大学博士论文发表期刊&#xff1a;Transactions on Software Engineering and Methodology (TOSEM)动机软件漏洞对推进漏洞分析和安全研究具有巨大的潜力&#xff0c;人们往往使用自然语言来描述软件漏洞的关键特征&#xff0c;并在…