【算法与数据结构】647、516、LeetCode回文子串+最长回文子序列

文章目录

  • 一、647、回文子串
  • 二、516、最长回文子序列
  • 三、完整代码

所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。

一、647、回文子串

在这里插入图片描述

  思路分析:判断一个字符串是否为回文串那么必须确定回文串的所在区间,而一维数组无法描述区间,因此我们需要用一个二维的dp数组来表示。我们只需要统计dp数组中回文串的个数即可。

  1. 第一步,动态数组的含义。 d p [ i ] [ j ] dp[i][j] dp[i][j]代表区间 [ i , j ] [i, j] [i,j](左闭右闭)的字符串是否为回文串。dp数组的类型为bool类型。
  2. 第二步,递推公式。 d p [ i ] [ j ] dp[i][j] dp[i][j]可以由两种情况推导出来:
  • s [ i ] s[i] s[i] s [ j ] s[j] s[j]相等:若 i = j i = j i=j,仅一个字符(例如a),那么必然是回文串;若 j − i = 1 j - i = 1 ji=1,两个字符(例如aa),那么也是回文串;剩下的情况: [ i , j ] [i, j] [i,j]的字符串是否为回文串与 [ i + 1 , j − 1 ] [i + 1, j - 1] [i+1,j1]的字符串是否为回文串相同,即 d p [ i ] [ j ] = d p [ i + 1 ] [ j − 1 ] dp[i][j] = dp[i + 1][j - 1] dp[i][j]=dp[i+1][j1]
  • s [ i ] s[i] s[i] s [ j ] s[j] s[j]不相等:那么 d p [ i ] [ j ] = f a l s e dp[i][j] = false dp[i][j]=false
	if (s[i] == s[j]) {
		if (j - i <= 1 || dp[i + 1][j - 1]) {
			result++;
			dp[i][j] = true;
		}
	}
	else dp[i][j] = false;
  1. 第三步,元素初始化。所有元素全部假设为false。
	vector<vector<bool>> dp(s.size(), vector<bool>(s.size(), false));
  1. 第四步,递归顺序。从递归公式 d p [ i ] [ j ] = d p [ i + 1 ] [ j − 1 ] dp[i][j] = dp[i + 1][j - 1] dp[i][j]=dp[i+1][j1]中可以看出, d p [ i ] [ j ] dp[i][j] dp[i][j]需要反对角线上的元素。因此我们需要先让最下面一行的元素先有结果。同时,按定义来说 d p [ i ] [ j ] dp[i][j] dp[i][j]是一个对称句矩阵,循环只要覆盖主对角线及其上方的元素即可(如图所示)。
  2. 第五步,打印结果。

在这里插入图片描述

  程序如下

// 647、回文子串-动态规划
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) O(n2)
  • 空间复杂度: O ( n 2 ) O(n^2) O(n2)

二、516、最长回文子序列

在这里插入图片描述

  思路分析:本题的分析思路和647题差不多。

  1. 第一步,动态数组的含义。 d p [ i ] [ j ] dp[i][j] dp[i][j]代表区间 [ i , j ] [i, j] [i,j](左闭右闭)的字符串的最大回文串长度。
  2. 第二步,递推公式。 d p [ i ] [ j ] dp[i][j] dp[i][j]可以由两种情况推导出来:
  • s [ i ] s[i] s[i] s [ j ] s[j] s[j]相等:那么 d p [ i ] [ j ] = d p [ i + 1 ] [ j − 1 ] + 2 dp[i][j] = dp[i + 1][j - 1] + 2 dp[i][j]=dp[i+1][j1]+2
  • s [ i ] s[i] s[i] s [ j ] s[j] s[j]不相等:那么说明加入 s [ i ] s[i] s[i] s [ j ] s[j] s[j]不能使回文串长度增加。那么单独加入 s [ i ] s[i] s[i] s [ j ] s[j] s[j]看看那个能组成最长的回文子序列,加入 s [ i ] s[i] s[i]的回文子序列长度为 d p [ i ] [ j − 1 ] dp[i][j-1] dp[i][j1],加入 s [ j ] s[j] s[j]的回文子序列长度为 d p [ i + 1 ] [ j ] dp[i+1][j] dp[i+1][j],二者取大值,即 d p [ i ] [ j ] = m a x ( d p [ i ] [ j − 1 ] , d p [ i + 1 ] [ j ] ) dp[i][j] = max(dp[i][j-1], dp[i+1][j]) dp[i][j]=max(dp[i][j1],dp[i+1][j])
	if (s[i] == s[j]) {
		dp[i][j] = dp[i + 1][j - 1] + 2;
	}
	else {
		dp[i][j] = max(dp[i][j - 1], dp[i + 1][j]);
	}
  1. 第三步,元素初始化。 i = j i = j i=j的一个字符串就是回文串,其他情况的dp数组元素全部初始化为0。
	vector<vector<bool>> dp(s.size(), vector<bool>(s.size(), 0));
	for (int i = 0; i < s.size(); i++) dp[i][i] = 1;
  1. 第四步,递归顺序。 d p [ i ] [ j ] dp[i][j] dp[i][j]依赖于 d p [ i + 1 ] [ j − 1 ] dp[i + 1][j - 1] dp[i+1][j1] d p [ i + 1 ] [ j ] dp[i + 1][j] dp[i+1][j] d p [ i ] [ j − 1 ] dp[i][j - 1] dp[i][j1]。那么递归顺序需要从下往上,从前往后递归。
  2. 第五步,打印结果。

在这里插入图片描述

  程序如下

// 516、最长回文子序列-动态规划
class Solution2 {
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][j - 1], dp[i + 1][j]);
			}
		}
		return dp[0][s.size() - 1];
	}
};

复杂度分析:

  • 时间复杂度: O ( n 2 ) O(n^2) O(n2)
  • 空间复杂度: O ( n 2 ) O(n^2) O(n2)

三、完整代码

# include <iostream>
# include <vector>
# include <string>
using namespace std;

// 647、回文子串-动态规划
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;
	}
};

// 516、最长回文子序列-动态规划
class Solution2 {
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][j - 1], dp[i + 1][j]);
			}
		}
		return dp[0][s.size() - 1];
	}
};

int main() {
	//string s = "aaa";	// 测试案例
	//Solution s1;
	//int result = s1.countSubstrings(s);

	string s = "bbbab";
	Solution2 s1;
	int result = s1.longestPalindromeSubseq(s);

	cout << result << endl;
	system("pause");
	return 0;
}

end

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

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

相关文章

SQL--DDL

全称 Structured Query Language&#xff0c;结构化查询语言。操作关系型数据库的编程语言&#xff0c;定义了 一套操作关系型数据库统一标准。 1 SQL通用语法 在学习具体的SQL语句之前&#xff0c;先来了解一下SQL语言的同于语法。 1). SQL语句可以单行或多行书写&#xff0…

处理SERVLET中的错误和异常

处理SERVLET中的错误和异常 应用服务器服务客户机请求时可能会遇到一些问题,如找不到所请求的资源或运行中的servlet引发异常。例如,在线购物门户中如果用户选择了当前缺货的物品要放入购物车中,就会出现问题, 这种情况下,浏览器窗口中将显示错误消息。您可以在servlet中…

Maven工程的配置及使用

一、Maven章节 Maven 是 Apache 软件基金会组织维护的一款专门为 Java 项目提供构建和依赖管理支持的工具 1.1、maven的作用 1&#xff09;依赖管理&#xff1a; 方便快捷的管理项目依赖的资源包&#xff08;jar包&#xff09;避免版本冲突 2&#xff09;统一项目结构&…

STC系列单片机的中断系统

目录 一、中断系统的定义 二、STC15系列单片机的中断请求源及结构图 三、中断查询表以及触发方式 四、在keil c中如何声明中断函数 五、外部中断 六、基于STC15芯片实战中断系统的使用 &#xff08;1&#xff09;外部中断2/外部中断3来检测门的开关状态 &#xff08;2&a…

【C++】- 继承(继承定义!!基本格式!切片概念!!菱形继承详解!)

继承 了解继承继承的定义基类和派生类对象赋值转换继承中的作用域派生类的默认成员函数继承和友元菱形继承和菱形虚拟继承 了解继承 继承机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许程序员在保 持原有类特性的基础上进行扩展&#xff0c;增加功能&a…

优化 IT 支出和消除浪费的 8 种主要方法

不懈追求最佳 IT 支出对于任何组织的长期可持续发展和成功都至关重要。在这个技术快速进步的时代&#xff0c;您必须做出明智的决策&#xff0c;消除浪费&#xff0c;同时最大限度地提高技术投资的价值。 从进行 IT 成本分析到采用敏捷预算和技术标准化&#xff0c;这些策略对…

关于服务器解析A记录和CNAME记录的分析

内容提要: 大致讲下理解,dns域名解析这一块 0 . 问题来源 最近搞了一个七牛云上传,然后需要配置融合cdn加速,也就是可以加速域名,中间有一部需要CNAME 域名,也就是将七牛云提供的域名CNAME一下,查阅资料其实就是起一个别名,好访问而已. 方便我们访问云存储,达到加速的效果. …

Elasticsearch(ES) 简述请求操作索引下文档 增删查改操作

上文 Elasticsearch(ES) 创建带有分词器规则的索引 带着大家创建了一个带有分词功能的索引 老规矩 我们启动一下ES服务 本文 我们就来说说 关于文档的操作 我们先来添加一个文档 就像数据库加一条数据一样 这里 并不需要指定什么表结构和数据结构 它的文档结构是无模式的 添…

es6中标签模板

之所以写这篇文章&#xff0c;是因为标签模板是一个很容易让人忽略的知识点 首先我们已经非常熟悉模板字符串的使用方法 const name "诸葛亮" const templateString hello, My name is ${name}标签模板介绍 这里的标签模板其实不是模板&#xff0c;而是函数调用…

2024年Java面试题大全 面试题附答案详解,BTA内部面试题

基础篇 1、 Java语言有哪些特点 1、简单易学、有丰富的类库 2、面向对象&#xff08;Java最重要的特性&#xff0c;让程序耦合度更低&#xff0c;内聚性更高&#xff09; 阿里内部资料 基本类型 大小&#xff08;字节&#xff09; 默认值 封装类 6、Java自动装箱与拆箱 装箱就是…

《幻兽帕鲁》解锁基地和工作帕鲁数量上限

帕鲁私服的游戏参数通常可通过配置文件 PalWorldSettings.ini 来进行修改&#xff0c;然而这个配置文件有个别参数对游戏不生效&#xff0c;让人很是头疼。没错&#xff01;我说的就是终端最大的帕鲁数量&#xff01; 其实还有另外一种更加高级的参数修改方式&#xff0c;那就…

《Python 网络爬虫简易速速上手小册》第2章:网络爬虫准备工作(2024 最新版)

文章目录 2.1 选择合适的爬虫工具和库2.1.1 重点基础知识讲解2.1.2 重点案例&#xff1a;使用 Scrapy 抓取电商网站2.1.3 拓展案例 1&#xff1a;使用 Requests 和 BeautifulSoup 抓取博客文章2.1.4 拓展案例 2&#xff1a;使用 Selenium 抓取动态内容 2.2 设置开发环境2.2.1 重…

【前沿技术杂谈:开源软件】引领技术创新与商业模式的革命

【前沿技术杂谈&#xff1a;开源软件】引领技术创新与商业模式的革命 开源软件如何推动技术创新开源软件的开放性和协作精神促进知识共享和技术迭代推动关键技术的发展开源软件与新技术的融合 开源软件的商业模式开源软件的商业模式将开源软件与商业软件相结合 开源软件的安全风…

Docker Dockerfile

1、概念介绍 Dockerfile是用来构建Docker镜像的文本文件&#xff0c;是由一条条构建镜像所需的指令和参数构成的脚本。 每条保留字指令都必须为大写字母且后面要跟随至少一个参数 指令按照从上到下&#xff0c;顺序执行 #表示注释 每条指令都会创建一个新的镜像层并对镜像进…

PyTorch 2.2 中文官方教程(十)

使用整体追踪分析的追踪差异 原文&#xff1a;pytorch.org/tutorials/beginner/hta_trace_diff_tutorial.html 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 作者: Anupam Bhatnagar 有时&#xff0c;用户需要识别由代码更改导致的 PyTorch 操作符和 CUDA 内核的变化…

vulhub中AppWeb认证绕过漏洞(CVE-2018-8715)

AppWeb是Embedthis Software LLC公司负责开发维护的一个基于GPL开源协议的嵌入式Web Server。他使用C/C来编写&#xff0c;能够运行在几乎先进所有流行的操作系统上。当然他最主要的应用场景还是为嵌入式设备提供Web Application容器。 AppWeb可以进行认证配置&#xff0c;其认…

【数据结构]排序算法之插入排序、希尔排序和选择排序

简单不先于复杂&#xff0c;而是在复杂之后。 文章目录 1. 排序的概念及其运用1.1 排序的概念1.2 排序运用1.3 常见的排序算法 2. 常见排序算法的实现2.1 插入排序2.1.1 基本思想2.1.2 直接插入排序2.1.3 希尔排序&#xff08;缩小增量排序&#xff09; 2.2. 选择排序2.2.1 基本…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Menu组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之Menu组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、Menu组件 TextClock组件通过文本将当前系统时间显示在设备上。支持不同时区的时间…

Ubuntu+GPU搭建Stable-Diffusion教程

【前序】已经安装anaconda 1.git拉取项目到本地 执行git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git 进入项目目录下 cd stable-diffusion-webui/ 2. 安装对应Python依赖包 首先安装pytorch和torchvision&#xff0c;若是GPU环境的用户需要安装与cu…

PHP入门指南:API

PHP入门指南&#xff1a;API 1. 简介2. API的基础概念2.1 什么是API&#xff1f;2.2 API的类型2.3 API的作用2.4 RESTful API2.5 API的基本构成元素 3. PHP与API的交互基础3.1 发送HTTP请求3.2 处理HTTP响应3.3 异常处理3.4 确保安全性 4. 如何在PHP中创建一个简单的API4.1 设计…