动态规划区间dp之647回文子串

news2024/11/27 12:34:17
题目:

给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度。

子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。

示例:

题目链接:647. 回文子串 - 力扣(LeetCode)

解法:

什么是回文字符串:字符串关于中心位置是对称的。

动规五部曲:

1确定dp数组以及下标的含义

布尔类型的dp[i][j]:表示区间范围[i,j] (注意是左闭右闭)的子串是否是回文子串,如果是dp[i][j]为true,否则为false。

2.确定递推公式

在确定递推公式时,就要分析如下几种情况。

整体上是两种,就是s[i]与s[j]相等,s[i]与s[j]不相等这两种。

当s[i]与s[j]不相等,那没啥好说的了,dp[i][j]一定是false。

当s[i]与s[j]相等时,这就复杂一些了,有如下三种情况

  • 情况一:下标i 与 j相同,同一个字符例如a,当然是回文子串
  • 情况二:下标i 与 j相差为1,例如aa,也是回文子串
  • 情况三:下标:i 与 j相差大于1的时候,例如cabac,此时s[i]与s[j]已经相同了,我们看i到j区间是不是回文子串就看aba是不是回文就可以了,那么aba的区间就是 i+1 与 j-1区间,这个区间是不是回文就看dp[i + 1][j - 1]是否为true。

以上三种情况分析完了,那么递归公式如下:

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;
    }
}

result就是统计回文子串的数量。

注意这里我没有列出当s[i]与s[j]不相等的时候,因为在下面dp[i][j]初始化的时候,就初始为false。

3.dp数组如何初始化

dp[i][j]可以初始化为true么? 当然不行,怎能刚开始就全都匹配上了。

所以dp[i][j]初始化为false。

4.确定遍历顺序

遍历顺序可有有点讲究了。

首先从递推公式中可以看出,情况三是根据dp[i + 1][j - 1]是否为true,在对dp[i][j]进行赋值true的。

dp[i + 1][j - 1] 在 dp[i][j]的左下角,如图:

647.回文子串

如果这矩阵是从上到下,从左到右遍历,那么会用到没有计算过的dp[i + 1][j - 1],也就是根据不确定是不是回文的区间[i+1,j-1],来判断了[i,j]是不是回文,那结果一定是不对的。

所以一定要从下到上,从左到右遍历,这样保证dp[i + 1][j - 1]都是经过计算的

有的代码实现是优先遍历列,然后遍历行,其实也是一个道理,都是为了保证dp[i + 1][j - 1]都是经过计算的。

5.举例推导dp数组:略

class Solution {
public:
    int countSubstrings(string s) 
    {
        int result=0;
        vector<vector<bool>> dp(s.size(), vector<bool>(s.size(), false));
        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 ((j - i > 1)&&dp[i + 1][j - 1]==true) 
                    { // 情况三
                        result++;
                        dp[i][j] = true;
                    }
                }
            }
        }
        return result;
    }
};

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

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

相关文章

Android 线程池源码详解(一)

线程池的创建是通过Executors 构造出来的&#xff0c;这是个典型的工厂类&#xff0c;使用了工厂模式。常用的有四种线程池&#xff1a; 分别是newFixedThreadPool&#xff0c;newSingleThreadExecutor&#xff0c; newCachedThreadPool&#xff0c;newScheduledThreadPool&am…

小白备战大厂算法笔试(二)——数组、链表、列表

常见数据结构 常见的数据结构包括数组、链表、栈、队列、哈希表、树、堆、图&#xff0c;它们可以从“逻辑结构”和“物理结构”两个维度进行分类。 逻辑结构可被分为“线性”和“非线性”两大类。线性结构比较直观&#xff0c;指数据在逻辑关系上呈线性排列&#xff1b;非线…

制药行业常见生产设备有哪些?

制药行业是一个关系到人民健康和生命安全的特殊领域&#xff0c;因此&#xff0c;生产质量和合规性是至关重要的。为了满足严格的生产质量管理规范&#xff08;GMP&#xff09;要求&#xff08;>>制药行业GMP是什么&#xff1f;&#xff09;&#xff0c;制药企业需要使用…

公司办公文件加密防泄密软件哪个好?

天锐绿盾是一款专业的数据安全解决方案&#xff0c;旨在保护企业的核心数据。它采用基于Windows、Mac、Linux内核的文档透明加解密技术&#xff0c;对指定类型的文件进行实时、强制、透明加密&#xff0c;使得文件在操作时自动解密&#xff0c;关闭时自动加密&#xff0c;能够有…

基于物理层网络编码的相位同步算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ..........................................................................%数据长度 Len…

前端(十七)——gitee上开源一个移动端礼盒商城项目(前端+后台)

&#x1f917;博主&#xff1a;小猫娃来啦 &#x1f917;文章核心&#xff1a;gitee上开源一个移动端礼盒商城项目 文章目录 前言开源地址项目运行命令项目基本展示前端效果细节展示视频前端代码细节展示视频后台效果展示后台代码展示经典优势思维导图实现思路 前言 项目样式老…

Redux中间件源码解析与实现

基本介绍 本文中涉及到的关键npm包的版本信息如下&#xff1a; react 的版本为18.2.0 redux的版本为4.1.2 redux-thunk版本为2.4.2 redux-promise版本为0.6.0 redux-logger版本为3.0.6 在Redux源码解析与实现&#xff08;一&#xff09;Redux源码解析与实现&#xff08;二&…

Python爬虫:下载小红书无水印图片、视频

该代码只提供学习使用&#xff0c;该项目是基于https://github.com/JoeanAmier/XHS_Downloader的小改动 1.下载项目 git clone https://github.com/zhouayi/XHS_Downloader.git2.找到需要下载的文章的ID 写入main.py中 3.下载 python main.py最近很火的莲花楼为例<嘿嘿…

【Java】传输层UDP

传输层UDP UDP基本特点无连接不可靠面向数据报缓冲区大小受限 UDP协议端格式16位UDP长度16位UDP检验和 UDP基本特点 UDP传输的过程类似于寄信 无连接,不可靠传输,面向数据报,全双工 无连接 知道对端的IP和端口号就直接进行传输&#xff0c;不需要建立连接&#xff1b; 不可…

Linux进程间通信(IPC)的几种方式

概述: “ 进程间通信&#xff08;IPC&#xff0c;Inter-Process Communication&#xff09;&#xff0c;指至少两个进程或线程间传送数据或信号的一些技术或方法。进程是计算机系统分配资源的最小单位(进程是分配资源最小的单位&#xff0c;而线程是调度的最小单位&#xff0c;…

java八股文面试[数据库]——行溢出

行记录格式 1) 行格式分类 表的行格式决定了它的行是如何物理存储的&#xff0c;这反过来又会影响查询和DML操作的性能。如果在单个page页中容纳更多行&#xff0c;查询和索引查找可以更快地工作&#xff0c;缓冲池中所需的内存更少&#xff0c;写入更新时所需的I/O更少。 I…

如何利用TikTok营销策略,来帮你赢得用户的心?

TikTok作为一款全球热门的短视频社交应用&#xff0c;已经成为许多品牌和营销人员的首选平台之一。作为一个出海公众号博主&#xff0c;我将在下面的文章中探讨TikTok营销的重要性、策略和成功案例。 首先&#xff0c;我们来谈一谈TikTok营销的重要性。随着移动互联网的迅速发…

突然发现ONLYOFFICE支持了.wps格式系列文件了

突然发现ONLYOFFICE支持了.wps格式系列文件了 最近做慕课&#xff0c;突然发现&#xff0c;我国产金山的WPS办公软件的.wps后缀名格式文件&#xff0c;居然被ONLYOFFICE这款办公软件支持打开了&#xff0c;找到官网仔细查看更新说明才确认就是最新一次更新加入的&#xff0c;并…

LabVIEW利用人工神经网络辅助进行结冰检测

LabVIEW利用人工神经网络辅助进行结冰检测 结冰对各个领域构成重大威胁&#xff0c;包括但不限于航空航天和风力涡轮机行业。在起飞过程中&#xff0c;飞机机翼上轻微积冰会导致升力降低25%。研究报告称&#xff0c;涡轮叶片上的冰堆积可在19个月的运行时间内造成29MWh的功率损…

View体系简析

应用程序中的View框架 应用程序中的View框架如图所示。 View和ViewRoot 如果以xml文件来描述UI界面的layout&#xff0c;可以发现里面的所有元素实际上都形成了树状结构的关系&#xff0c;比如&#xff1a; <LinearLayout xmlns:android"http://schemas.android.c…

算法通关村-----快速排序的应用

数组中的第K个最大元素 问题描述 给定整数数组 nums 和整数 k&#xff0c;请返回数组中第 k 个最大的元素。请注意&#xff0c;你需要找的是数组排序后的第 k 个最大的元素&#xff0c;而不是第 k 个不同的元素。详见leetcode215 问题分析 之前我们已经使用堆排序/堆查找的…

群晖NAS:黑群cpu信息显示不正确修正

群晖NAS&#xff1a;黑群cpu信息显示不正确修正 黑群晖的面板信息&#xff0c;cpu信息一直是错误的&#xff0c;很难受&#xff0c;修正方法如下&#xff1a; 【1】下载插件&#xff1a; 打开&#xff1a; https://github.com/FOXBI/ch_cpuinfo/releases 下载&#xff1a; …

图像分割笔记(二): 使用YOLOv5-Seg对图像进行分割检测完整版(从自定义数据集到测试验证的完整流程))

文章目录 一、图像分割介绍二、YOLOv5-Seg介绍三、代码获取四、视频讲解五、环境搭建六、数据集准备6.1 数据集转换6.2 数据集验证七、模型训练八、模型验证九、模型测试十、评价指标一、图像分割介绍 图像分割是指将一幅图像划分为若干个互不重叠的区域,每个区域内的像素具有…

win7打开文件夹总弹出新窗口怎么办

我们在使用电脑打开文件夹时&#xff0c;都是在同一个窗口显示&#xff0c;查看非常方便&#xff0c;如果遇到每次打开文件夹弹出新窗口就总觉得很烦人&#xff0c;下面就一起来看看解决win7文件夹每次打开新窗口的方法。 一、 使用360或相关杀毒软件查杀木马&#xff0c;完成…

Kafka3.0.0版本——文件存储机制

这里写木目录标题 一、Topic 数据的存储机制1.1、Topic 数据的存储机制的概述1.2、Topic 数据的存储机制的图解1.3、Topic 数据的存储机制的文件解释 二、Topic数据的存储位置示例 一、Topic 数据的存储机制 1.1、Topic 数据的存储机制的概述 Topic是逻辑上的概念&#xff0c…