力扣LeetCode: 5 最长回文子串

题目:

给你一个字符串 s,找到 s 中最长的回文子串。

示例 1:

输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。

示例 2:

输入:s = "cbbd"
输出:"bb"

提示:

  • 1 <= s.length <= 1000
  • s 仅由数字和英文字母组成

解法一:直接暴力枚举

        第一个想到就是暴力枚举。但我还是有点自己的心思的。

代码结构

代码分为两个主要部分:

  1. isPalindrome 函数:用于判断一个子串是否是回文。

  2. longestPalindrome 函数:用于遍历字符串,找到最长的回文子串。


isPalindrome 函数

bool isPalindrome(string s, int left, int right) {while (left < right) {if (s[left] == s[right]) {left++;right--;} else {return false;}}return true;
}

功能

  • 判断字符串 s 中从索引 left 到 right 的子串是否是回文。

逻辑

  1. 使用双指针法:

    • left 指针从子串的起始位置开始,向右移动。

    • right 指针从子串的结束位置开始,向左移动。

  2. 比较 s[left] 和 s[right]

    • 如果相等,则继续向中间移动指针。

    • 如果不相等,则说明子串不是回文,返回 false

  3. 如果 left 和 right 指针相遇或交叉,说明子串是回文,返回 true

时间复杂度

  • 每次调用 isPalindrome 的时间复杂度是 O(n),其中 n 是子串的长度。


longestPalindrome 函数

string longestPalindrome(string s) {string ans;int length = 0;for (int left = 0; left < s.size(); left++) {for (int right = left; right < s.size(); right++) {if (s[left] == s[right]) {if (isPalindrome(s, left, right) && (right - left + 1) > length) {length = right - left + 1;ans = s.substr(left, right - left + 1);}} else {continue;}}}return ans;
}

功能

  • 遍历字符串 s,找到最长的回文子串。

逻辑

  1. 初始化:

    • ans:用于存储当前找到的最长回文子串。

    • length:用于记录当前找到的最长回文子串的长度。

  2. 双重循环:

    • 外层循环:left 指针从字符串的起始位置开始,向右移动。

    • 内层循环:right 指针从 left 的位置开始,向右移动。

  3. 检查子串是否是回文:

    • 如果 s[left] == s[right],则检查从 left 到 right 的子串是否是回文。

    • 如果是回文,并且子串的长度 (right - left + 1) 大于当前记录的 length,则更新 length 和 ans

  4. 返回结果:

    • 最终返回 ans,即最长的回文子串。

完整代码

class Solution {
public://判断是不是回文串bool isPalindrome(string s, int left, int right){// int left = 0;// int right = s.size();while(left < right){if(s[left] == s[right]){left++;right--;}else{return false;}}return true;}string longestPalindrome(string s) {string ans;int length = 0;for(int left = 0; left < s.size(); left++){for(int right = left; right < s.size(); right++){if(s[left] == s[right]){if(isPalindrome(s, left, right) && (right - left + 1) > length){length = right - left + 1;ans = s.substr(left, right - left + 1);}}else{continue;}}}return ans;}
};

问题是:时间复杂度O(n^3)。虽然做了很多简化,但是还有一个用例没有通过!!!

解法二:中心拓展法

class Solution {
public:string longestPalindrome(string s) {if (s.empty()) return "";int start = 0, maxLength = 1; // 记录最长回文子串的起始位置和长度for (int i = 0; i < s.size(); i++) {// 奇数长度的回文子串int len1 = expandAroundCenter(s, i, i);// 偶数长度的回文子串int len2 = expandAroundCenter(s, i, i + 1);// 取较长的回文子串int len = max(len1, len2);if (len > maxLength) {maxLength = len;start = i - (len - 1) / 2; // 计算起始位置}}return s.substr(start, maxLength);}private:// 中心扩展函数int expandAroundCenter(const string& s, int left, int right) {while (left >= 0 && right < s.size() && s[left] == s[right]) {left--;  // 向左扩展right++; // 向右扩展}// 返回当前回文子串的长度return right - left - 1;}
};

中心扩展法的逻辑

  1. 核心思想

    • 回文子串的中心可能是 一个字符(奇数长度)或 两个字符(偶数长度)。

    • 遍历字符串,以每个字符为中心,向左右扩展,找到最长的回文子串。

  2. 具体步骤

    • 遍历字符串中的每个字符 s[i]

    • 对于每个字符 s[i],分别以 s[i] 为中心(奇数长度)和以 s[i] 和 s[i+1] 为中心(偶数长度)进行扩展。

    • 使用 expandAroundCenter 函数向左右扩展,直到字符不匹配或超出字符串边界。

    • 记录每次扩展得到的回文子串的长度,并更新最长回文子串的起始位置和长度。

  3. 时间复杂度

    • 遍历字符串需要 O(n),每次扩展需要 O(n),总时间复杂度为 O(n^2)。

  4. 空间复杂度

    • 只使用了常数级别的额外空间,空间复杂度为 O(1)。

解法三:动态规划

class Solution {
public:string longestPalindrome(string s) {if (s.empty()) return "";int n = s.size();vector<vector<bool>> dp(n, vector<bool>(n, false)); // dp[i][j] 表示 s[i..j] 是否是回文int start = 0, maxLength = 1; // 记录最长回文子串的起始位置和长度// 单个字符一定是回文for (int i = 0; i < n; i++) {dp[i][i] = true;}// 检查长度为 2 的子串for (int i = 0; i < n - 1; i++) {if (s[i] == s[i + 1]) {dp[i][i + 1] = true;start = i;maxLength = 2;}}// 检查长度大于 2 的子串for (int len = 3; len <= n; len++) { // len 是子串的长度for (int i = 0; i <= n - len; i++) { // i 是子串的起始位置int j = i + len - 1; // j 是子串的结束位置if (s[i] == s[j] && dp[i + 1][j - 1]) { // 状态转移dp[i][j] = true;if (len > maxLength) {start = i;maxLength = len;}}}}return s.substr(start, maxLength);}
};

动态规划法的逻辑

  1. 核心思想

    • 使用一个二维数组 dp[i][j] 表示子串 s[i..j] 是否是回文。

    • 通过状态转移方程,利用已知的小规模回文子串信息,推导出更大规模的回文子串。

  2. 状态转移方程

    • 如果 s[i] == s[j],并且 dp[i+1][j-1] 是回文,那么 dp[i][j] 也是回文。

    • 即:dp[i][j] = (s[i] == s[j]) && dp[i+1][j-1]

  3. 初始化

    • 单个字符一定是回文:dp[i][i] = true

    • 两个字符的子串:如果 s[i] == s[i+1],则 dp[i][i+1] = true

  4. 具体步骤

    • 遍历所有可能的子串长度 len,从 3 到 n

    • 对于每个长度 len,遍历所有可能的起始位置 i,计算结束位置 j = i + len - 1

    • 根据状态转移方程更新 dp[i][j],并记录最长回文子串的起始位置和长度。

  5. 时间复杂度

    • 需要填充一个 n x n 的二维数组,时间复杂度为 O(n^2)。

  6. 空间复杂度

    • 需要一个 n x n 的二维数组,空间复杂度为 O(n^2)。

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

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

相关文章

【MySQL例题】我在广州学Mysql 系列——有关数据备份与还原的示例

ℹ️大家好&#xff0c;我是练小杰&#xff0c;今天周二&#xff0c;明天就是元宵节了呀&#xff01;&#xff01;&#x1f606; 俗话说“众里寻他千百度。蓦然回首&#xff0c;那人却在&#xff0c;灯火阑珊处。” 本文主要对数据库备份与还原的知识点例题学习~~ 前情回顾&…

自动化xpath定位元素(附几款浏览器xpath插件)

在 Web 自动化测试、数据采集、前端调试中&#xff0c;XPath 仍然是不可或缺的技能。虽然 CSS 选择器越来越强大&#xff0c;但面对复杂 DOM 结构时&#xff0c;XPath 仍然更具灵活性。因此&#xff0c;掌握 XPath&#xff0c;不仅能提高自动化测试的稳定性&#xff0c;还能在爬…

【并发控制、更新、版本控制】.NET开源ORM框架 SqlSugar 系列

系列文章目录 &#x1f380;&#x1f380;&#x1f380; .NET开源 ORM 框架 SqlSugar 系列 &#x1f380;&#x1f380;&#x1f380; 文章目录 系列文章目录一、并发累计&#xff08;累加&#xff09;1.1 单条批量累计1.2 批量更新并且字段11.3 批量更新并且字段list中对应的…

数据存储和操作:数据管理的基石

在数据管理的庞大体系中&#xff0c;数据存储和操作是确保数据可用性和完整性的关键环节。它不仅涉及数据的物理存储&#xff0c;还包括数据的管理、维护和优化。今天&#xff0c;让我们深入《DAMA数据管理知识体系指南&#xff08;第二版&#xff09;》的第六章&#xff0c;一…

Redis 数据类型 Hash 哈希

在 Redis 中&#xff0c;哈希类型是指值本⾝⼜是⼀个键值对结构&#xff0c;形如 key "key"&#xff0c;value { { field1, value1 }, ..., {fieldN, valueN } }&#xff0c;Redis String 和 Hash 类型⼆者的关系可以⽤下图来表⽰。 Hash 数据类型的特点 键值对集合…

支持向量机原理

支持向量机&#xff08;简称SVM&#xff09;虽然诞生只有短短的二十多年&#xff0c;但是自一诞生便由于它良好的分类性能席卷了机器学习领域。如果不考虑集成学习的算法&#xff0c;不考虑特定的训练数据集&#xff0c;尤其在分类任务中表现突出。在分类算法中的表现SVM说是排…

zy.21

PHP(续) PHP代码执行漏洞 1.PHP中代码漏洞的概念 代码执行漏洞就是在代码中若存在eval、assert等能将所接收的参数作为代码去执行,并且拼接的内容可被访问者控制,也就是把传入的参数给拼接进去了,造成了额外的代码执行,也就造成了代码执行漏洞。&#xff08;大概原理&#x…

LSTM 学习笔记 之pytorch调包每个参数的解释

0、 LSTM 原理 整理优秀的文章 LSTM入门例子&#xff1a;根据前9年的数据预测后3年的客流&#xff08;PyTorch实现&#xff09; [干货]深入浅出LSTM及其Python代码实现 整理视频 李毅宏手撕LSTM [双语字幕]吴恩达深度学习deeplearning.ai 1 Pytorch 代码 这里直接调用了nn.l…

React - 事件绑定this

在 React 中&#xff0c;this 的绑定是一个常见问题&#xff0c;尤其在类组件中使用事件处理函数时。JavaScript 中的 bind 函数用于设置函数调用时 this 的值。 bind 函数的作用 bind() 方法创建一个新的函数&#xff0c;当被调用时&#xff0c;其 this 关键字被设置为提供的…

Web3 的虚实融合之路:从虚拟交互到元宇宙构建

在这个数字技术日新月异的时代&#xff0c;我们正站在 Web3 的门槛上&#xff0c;见证着互联网的又一次革命。Web3 不仅仅是技术的迭代&#xff0c;它代表了一种全新的交互方式和价值创造模式。本文将探讨 Web3 如何推动虚拟交互的发展&#xff0c;并最终实现元宇宙的构建&…

Kafka简单使用

说明&#xff1a;kafka是一款消息中间件&#xff0c;可实现微服务之间的异步调用。本文介绍kafka的简单使用。windows操作系统下的kafka安装&#xff0c;参考下面这篇文章 Kafka安装 启动 按照上面博客的介绍&#xff0c;使用CMD命令启动&#xff0c;如下&#xff1a; Demo …

【原创精品】基于Springboot3+Vue3的学习计划管理系统

大家好&#xff0c;我是武哥&#xff0c;最近给大家手撸了一个基于SpringBoot3Vue3的学习计划管理系统&#xff0c;可用于毕业设计、课程设计、练手学习&#xff0c;系统全部原创&#xff0c;如有遇到网上抄袭站长的&#xff0c;欢迎联系博主~ 项目演示视频 https://www.bili…

C++引用深度详解

C引用深度详解 前言1. 引用的本质与核心特性1.1 引用概念1.2 核心特性 2. 常引用与权限控制2.1 权限传递规则2.2 常量引用2.3 临时变量保护1. 样例2. 样例3. 测试 三、引用使用场景分析3.1 函数参数传递输出型参数避免多级指针高效传参 3.2 做函数返回值正确使用危险案例 4. 性…

本地部署Deepseek R1

使用Ollama open-webui部署Deepseek R1 一、安装Ollama 官网地址&#xff1a;https://ollama.com/&#xff0c;点击下载按钮选择windows版本。并安装 打开命令提示符输入ollama&#xff0c;出现一下提示命令表示ollama安装完成 二、使用Ollama下载deepseek R1不同模型 打开o…

MATLAB 生成脉冲序列 pulstran函数使用详解

MATLAB 生成脉冲序列 pulstran函数使用详解 目录 前言 一、参数说明 二、示例一 三、示例二 总结 前言 MATLAB中的pulstran函数用于生成脉冲序列&#xff0c;支持连续或离散脉冲。该函数通过将原型脉冲延迟并相加&#xff0c;生成脉冲序列&#xff0c;适用于信号处理和系统…

机器学习(李宏毅)——self-Attention

一、前言 本文章作为学习2023年《李宏毅机器学习课程》的笔记&#xff0c;感谢台湾大学李宏毅教授的课程&#xff0c;respect&#xff01;&#xff01;&#xff01; 二、大纲 何为self-Attention&#xff1f;原理剖析self-Attention VS CNN、RNN、GNN 三、何为self-Attenti…

RagFlow + Docker Desktop + Ollama + DeepSeek-R1本地部署自己的本地AI大模型工具

前期准备 首先&#xff0c;我们需要下载 Ollama 以及配置相关环境。 Ollama 的 GitHub仓库 &#xff08;https://github.com/ollama/ollama&#xff09;中提供了详细的说明&#xff0c;简单总结如下: Step1&#xff1a;下载 Ollama 下载&#xff08;https://ollama.com/dow…

【数据结构】双向链表(真正的零基础)

链表是一种物理存储单元上非连续、非顺序的存储结构。数据元素的逻辑顺序是通过指针的链接来实现的&#xff01;在上篇我们学习了单向链表&#xff0c;而单向链表虽然空间利用率高&#xff0c;插入和删除也只需改变指针就可以达到&#xff01;但是我们在每次查找、删除、访问..…

网络编程-day5-sqlite3数据库

思维导图 服务器 #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <pthread.h> #include <semaphore.h>…

Spring AI 介绍

文章来源&#xff1a;AI 概念 (AI Concepts) _ Spring AI1.0.0-SNAPSHOT中文文档(官方文档中文翻译)|Spring 教程 —— CADN开发者文档中心 本节介绍 Spring AI 使用的核心概念。我们建议仔细阅读它&#xff0c;以了解 Spring AI 是如何实现的。 模型 AI 模型是旨在处理和生成…