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

【leetcode】5 最长回文子串 动态规划法

题目:
给你一个字符串 s,找到 s 中最长的 回文 子串。
分析:题目很简单,首先思路是遍历一下字符串的所有子串,判断一下是否是回文,然后再判断长度是不是最长的。

class Solution {public boolean isPalindrome(String z){for(int i=0;i<z.length();i++){//需要同时移动i和j,保证i和j是同时移动的if(z.charAt(i)!=z.charAt(z.length()-1-i)){return false;}//或者用这个}return true;}public String longestPalindrome(String s) {//寻找回文子串,需要保留原始字符的顺序。不能使用哈希表//使用双指针,移动指针进行遍历int i=0;int j=0;int maxi=0;int maxj=0;int maxl=0;for(i=0;i<s.length()-1;i++){j=s.length()-1;while(!isPalindrome(s.substring(i,j+1))){j--;}if(maxl<j-i+1){maxi=i;maxj=j;maxl=j-i+1;}}return s.substring(maxi,maxj+1);}
}

此思路需要注意的内容:此思路是暴力解法,时间复杂度较高
主要涉及到两个大块的循环思路:
1.获得字符串的子串(使用左右指针,固定左指针,逐渐移动右指针缩小子串长度、当子串为回文子串时停止此次循环,并移动左指针再次寻找)
2.·循环判断子串是否是回文串(按照回文子串的特性,需要从字符串的两头开始遍历、且需保证两头是同时移动的)

⚠️s.substring(a,b)方法是左闭右开

有没有时间复杂度更小的方法呢?——动态规划
1.什么是动态规划法
通过拆分问题、存储中间结果来得到最优解的方法。
四个步骤如下:

  • 1.1.定义状态:定义子问题的解,通常用dp[i](一维)或dp[i][j](二维)等数组存储,例如dp[i]可表示 “前 i 个元素的最优解”。
  • 1.2.确定状态转移方程:如何通过已知子问题的解推出更大子问题的解。
  • 1.3.确定最小子问题的解(即无法再拆分的基础情况)
  • 1.4.计算并存储结果
    2.动态规划法适用于什么样的问题:重叠子问题(问题的子问题之间存在重复)+最优子结构(问题最优解包含着子问题的最优解、可以通过子问题的最优解推导出原问题的最优解)
    3.那此问题是否符合动态规划法呢?
    重叠子问题:不同范围的子串判断依赖相同的更小的子串判断;
    最优子结构:最长回文子串的解依赖于更小的回文子串的解。(最)

基于以上信息分析本题:
1.定义状态:dp[i][j]表示i到j的字符串
2.状态转移方程:i到j的字符串为回文串i+1到j-1的字符串为回文串
3.最小子问题的解(边界情况):当i
j时,字符串肯定是回文串,或者i==i+1,字符串肯定是回文串。
代码为:

public class Solution {public String longestPalindrome(String s) {int len = s.length();if (len < 2) {return s;}int maxLen = 1;int begin = 0;// dp[i][j] 表示 s[i..j] 是否是回文串boolean[][] dp = new boolean[len][len];// 初始化:所有长度为 1 的子串都是回文串for (int i = 0; i < len; i++) {dp[i][i] = true;}char[] charArray = s.toCharArray();// 递推开始// 先枚举子串长度for (int L = 2; L <= len; L++) {// 枚举左边界,左边界的上限设置可以宽松一些for (int i = 0; i < len; i++) {//长度固定后,通过确定左边界,就可以得知右边界。即 j - i + 1 = L int j = L + i - 1;// 如果右边界越界,就可以退出当前循环if (j >= len) {break;}if (charArray[i] != charArray[j]) {dp[i][j] = false;} else {if (j - i < 3) {dp[i][j] = true;} else {//判断子串是否是回文串dp[i][j] = dp[i + 1][j - 1];}}// 只要 dp[i][j] == true 成立,就表示子串 s[i..j] 是回文,此时记录回文长度和起始位置if (dp[i][j] && j - i + 1 > maxLen) {maxLen = j - i + 1;begin = i;}}}return s.substring(begin, begin + maxLen);}
}

循环中的思路是:
1.最外层是子串的长度,从2一直到最长。长度为1的子串肯定是回文子串

http://www.xdnf.cn/news/17878.html

相关文章:

  • Protues使用说明及Protues与Keil联合仿真实现点亮小灯和流水灯
  • 【Docker项目实战】使用Docker部署Notepad轻量级记事本
  • 【基础-判断】HarmonyOS提供了基础的应用加固安全能力,包括混淆、加密和代码签名能力
  • 数据结构 实现循环队列的三种方法
  • 如何在 MacOS 上安装 SQL Server
  • 搭建ktg-mes
  • 新手向:Python列表、元组、集合和字典的用法对比
  • MySQL的三大范式:
  • AI云电脑盒子技术分析——从“盒子”到“算力云边缘节点”的跃迁
  • 实现Android图片手势缩放功能的完整自定义View方案,结合了多种手势交互功能
  • Vue 3.5重磅更新:响应式Props解构,让组件开发更简洁高效
  • MQ积压如何处理
  • Markdown 生成 Gantt 甘特图
  • 使用js完成抽奖项目 效果和内容自定义,可以模仿游戏抽奖页面
  • 31 HTB Union 机器 - 中等难度
  • C:\Windows\WinSxS 目录详解
  • 【C++】标准库中用于组合多个值的数据结构pair、tuple、array...
  • AI搜索引擎下的内容优化新范式:GEO的关键技术解析
  • 二十七、动态SQL
  • RK3568 NPU RKNN(三):RKNN-ToolKit2模型构建与推理
  • 大模型教机器人叠衣服:2025年”语言理解+多模态融合“的智能新篇
  • PowerPoint和WPS演示放映PPT时如何禁止鼠标翻页
  • 玉米及淀粉深加工产业展|2026中国(济南)国际玉米及淀粉深加工产业展览会
  • Java 学习笔记(基础篇3)
  • 数据结构:构建 (create) 一个二叉树
  • 【数据结构入门】二叉树(2)
  • 内网穿透实战笔记 1panel 面板部署 frps,Windows 部署 frpc
  • Ubuntu永久配置 DNS
  • JavaScript 原型机制详解:从概念到实战(附个人学习方法)
  • 【Mysql语句练习】