文章目录

  • 一、回文串、子串、子序列
  • 二、最长回文子串
    • 1、动态规划算法
    • 2、动态规划算法代码示例

一、回文串、子串、子序列


" 回文串 ( Palindrome ) " 是 正反都一样的字符串 , abccba , 001100 等字符串 ;

给定一个字符串 " abcd " ,

" 子串 ( SubString ) "是连续取的子字符串 , 如 : “ab” , “bc” , “cd” , “bcd” 等 , 不能跳跃字符 ; ( 连续字符 )

nnn 个字符串的子串个数是 n(n+1)2+1\cfrac{n(n+1)}{2} +12n(n+1)​+1 个 ;

" 子序列 ( SubSequence ) " 是可以非连续取字符串中的字符 , 前后顺序不允许颠倒 , 如 “ad” , “bd” , “acd” 等 ; ( 非连续字符 )

nnn 个字符串的子串个数是 2n2^n2n 个 ( 集合的子集数 ) ;

验证一个字符串是否是回文串 , 最坏的情况下需要遍历 n2\cfrac{n}{2}2n​ 次 ;

因此最暴力的方法验证回文子串 , 就是验证 n(n+1)2+1\cfrac{n(n+1)}{2} +12n(n+1)​+1 个子字符串是否是回文串 , 每次都要遍历 n2\cfrac{n}{2}2n​ 次 ;
暴力算法的时间复杂度是 O(n3)O(n^3)O(n3) ;

二、最长回文子串


问题链接 : https://www.lintcode.com/problem/200/description

给出一个字符串(假设长度最长为1000),求出它的最长回文子串,你可以假定只有一个满足条件的最长回文串。

1、动态规划算法

如果不使用中心线枚举算法 , 在蛮力算法的基础上 , 快速判定字符串是否是回文串 ;
使用基于动态规划的算法可以实现上述要求 ;

回文串存在特点 :
两种类型的回文串 “abba” , “abcba” , 正序 和 倒序 是一样的 ;
回文串两头的字符相等 ;
回文串除去两头的两个字符 , 中间部分也是回文串 ;

字符串中 iii ~ jjj 之间的字符串是回文串 ;

  • 则 i,ji, ji,j 字符相等 ,
  • 并且 i+1i +1i+1 ~ j−1j - 1j−1 的字符串也是回文串 ;

iii ~ jjj 之间的字符串是否是回文串 , 依赖于 i+1i +1i+1 ~ j−1j - 1j−1 之间的字符串是否是回文串 ;
因此推导任意两个索引区间 i,ji, ji,j 之间的字符串是否是回文串时 ,

将 i,ji, ji,j 之间的字符串是否是回文串 , 存储在一个二维布尔数组中 ;

// 表示 n 个字符串中所有的字符索引之间是否是回文串
boolean [][] isPalindrome = new boolean[n][n];

isPalindrome[i][j] 表示 iii ~ jjj 之间的字符串是否是回文串 , 如果是回文串则设置为 true , 如果不是回文串则设置为 false ;

回文串判定条件 :

isPalindrome[i][j] = isPalindrome[i + 1][j - 1] && s.charAt(i) == s.charAt(j);

iii ~ jjj 之间的字符串是回文串 , 则 i+1i +1i+1 ~ j−1j - 1j−1 之间的字符串也是回文串 , 并且第 iii 个字符等于第 jjj 个字符 ;

动态规划 :

这种推导公式在 动态规划 中 , 称为 状态转移方程 ;

isPalindrome 二维数组中每个元素都是一个 状态 , 这个状态是以区间作为状态的标志 , 两个维度的值分别是区间的开始索引和结束索引 ;

这种类型的动态规划 , 又称为 区间型动态规划 ;

循环设计 :

iii ~ jjj 之间的字符串是否是回文串 , 依赖于 i+1i +1i+1 ~ j−1j - 1j−1 之间的字符串是否是回文串 ;

也就是 iii 依赖于 i+1i + 1i+1 , 循环时 , 不能正向循环 , 只能倒序循环 ;

先计算 iii 比较大的 , 再计算 iii 比较小的 ;

初始化操作 : 动态规划中初始化很重要 ;

这里要考虑公式的适用性 , 上述公式

isPalindrome[i][j] = isPalindrome[i + 1][j - 1] && s.charAt(i) == s.charAt(j);

公式中使用了 i+1i + 1i+1 , j−1j - 1j−1 , 为了保证公式成立 , 字符串的字符个数至少要有 222 个 ;

初始化时最好将空字符串 , 111 个字符组成的字符串 的情况直接初始化赋值 ;

初始化单个字符字符串的状态 :

isPalindrome[i][i] 是第 iii 个字符到第 iii 个字符之间的单个字符是否是回文串 , 显然单个字符是回文串 ;

isPalindrome[i][i] = true

2、动态规划算法代码示例

代码示例 :

class Solution {/*** @param s: 输入字符串* @return: 返回最长回文子串*/public String longestPalindrome(String s) {if (s == null || "".equals(s)) {return null;}int n = s.length();boolean[][] isPalindrome = new boolean[n][n];int longest = 1;    // 最长长度int start = 0;      // 开始索引// 初始化操作, 长度为 1 的回文串for (int i = 0; i < n; i++) {isPalindrome[i][i] = true;}// 初始化操作, 长度为 2 的回文串for (int i = 0; i < n - 1; i ++) {if (s.charAt(i) == s.charAt(i + 1)) {isPalindrome[i][i + 1] = true;start = i;longest = 2;}else {isPalindrome[i][i + 1] = false;}}// 倒序遍历for (int i = n - 1; i >= 0; i--) {// 从 i + 2 开始计算 , 之前 i , i + 1 都已经计算过了 , 从长度为 3 的区间开始计算// 注意此处如果 j >= n 时 , 不进入内层循环 // 只有在 j <= n - 1 时 , 才进入内层循环 for (int j = i + 2; j < n; j ++) {isPalindrome[i][j] = isPalindrome[i + 1][j - 1] && s.charAt(i) == s.charAt(j);if (isPalindrome[i][j] && j - i + 1 > longest) {start = i;longest = j - i + 1;}}}return s.substring(start, start + longest);}
}class Main {public static void main(String[] args) {String palindrome = new Solution().longestPalindrome("mabcban");System.out.println(palindrome);}
}

O(n2)O(n^2)O(n2) 时间复杂度算法;

【字符串】最长回文子串 ( 动态规划算法 ) ★相关推荐

  1. HihoCode1032 最长回文子串 manacher算法

    求最长回文子串的算法比较经典的是manacher算法 转载自这里 首先,说明一下用到的数组和其他参数的含义: (1)p[i] : 以字符串中下标为的字符为中心的回文子串半径长度: 例如:abaa字符串 ...

  2. 字符串最长回文子串_最长回文子串

    字符串最长回文子串 Problem statement: 问题陈述: Given a string str, find the longest palindromic substring. A sub ...

  3. 最长回文子串动态规划_九章算法 | 微软面试题:最长回文子串

    给出一个字符串(假设长度最长为1000),求出它的最长回文子串,你可以假定只有一个满足条件的最长回文串. 在线评测地址:LintCode 领扣 样例 1: 输入:"abcdzdcab&quo ...

  4. 【字符串】最长回文子串 ( 蛮力算法 )

    文章目录 一.回文串.子串.子序列 二.最长回文子串 1.蛮力算法 2.时间复杂度最优方案 一.回文串.子串.子序列 " 回文串 ( Palindrome ) " 是 正反都一样的 ...

  5. java最长回文子序列_LeetCode[5] - 最长回文子串动态规划

    题目 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为1000. 示例 1: 输入: "babad" 输出: "bab" 注意: & ...

  6. 最长回文子串——Manacher 算法​​​​​​​

    0. 问题定义 最长回文子串问题:给定一个字符串,求它的最长回文子串长度. 如果一个字符串正着读和反着读是一样的,那它就是回文串.下面是一些回文串的实例: 12321 a aba abba aaaa ...

  7. 最长回文子串--动态规划

    问题来源:最长回文子串 问题描述:给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 例子: 输入: "babad" 输出: "ba ...

  8. lintcode最长回文子串(Manacher算法)

    题目来自lintcode, 链接:http://www.lintcode.com/zh-cn/problem/longest-palindromic-substring/ 最长回文子串 给出一个字符串 ...

  9. 求解最长回文子串----Manacher 算法

    最长回文子串问题:给定一个字符串,求它的最长回文子串长度. 如果一个字符串正着读和反着读是一样的,那么我们称之为回文串.例如:abba.aaaa.abvcba.123321等 暴力法:遍历字符串的所有 ...

最新文章

  1. 自动驾驶有量子飞跃式改进,马斯克称年内实现L5级别自动驾驶?
  2. FreeMarker基本语法详解及模板文件的组成(二)
  3. phpmyadmin修改mysql数据库_用phpMyAdmin修改mysql数据库密码
  4. django的页面报错中出现xxxx.html (Skipped)
  5. vue axios POST请求中参数以form data和request payload形式的原因
  6. 杨中科的.NET 6新书的出版进度汇报
  7. 你真的清楚DateTime in C#吗?
  8. 在建工地扬尘在线监控系统推荐_vocs在线监控系统安装的法规依据
  9. list遍历_Qt 容器类之遍历器和隐式数据共享
  10. 【华为云技术分享】基于自动机器学习的心脏病预测模型(1)
  11. c# Open Source
  12. Loadrunner -27225错误
  13. 服务端开发所需技能归纳
  14. 小谈暴风影音并给个小建议
  15. 如何用数据驱动的广告效果
  16. 计算机等级考试报名班级填什么,全国计算机等级考试报名流程
  17. Excel--Vlookup与match、index函数
  18. php think命令,ThinkPHP 使用命令行 (cli) think 调用
  19. 二、Nio之Channel
  20. PHP取小数点后一位小数或几位小数并且不四舍五入,以及四舍五入保留小数

热门文章

  1. 在django中使用django_debug_toolbar
  2. spring boot(一)创建项目
  3. python学习-----9.7-----GIL、死锁递归锁、信号量,event事件
  4. 2017滴滴出行笔试题:异或和为0的最大区间个数
  5. 二、Windows基础数据类型
  6. chgrp 简明笔记
  7. cocos2d-x 3.2 listview scorllview 等容器在小米华为等部分手机显示泛白解决
  8. setjmp()、longjmp() Linux Exception Handling/Error Handling、no-local goto
  9. Tomcat绿色版启动startup.bat一闪问题的解决方法!
  10. MFC DLL对话框调用