题目:
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:
输入: "cbbd"
输出: "bb"
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-palindromic-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
 
方法一:将字符串倒置 ,找出公共字符串子串->确定最后碰到了自己
StringBuilder strR=new StringBuilder(s).reverse();//倒置
int len=s.length();
int[][] arr=new int[len][len];
int maxlen=0;
int startIndex=0; for(int i=0;i<len;i++) {
for(int j=0;j<len;j++) {
if(s.charAt(i)==strR.charAt(j)) {
if(i==0||j==0) arr[i][j]=1;//边界
else arr[i][j]=arr[i-1][j-1]+1;
}
//len-j-1+arr[i][j]-1==j j(末尾的下标)-(len-j-1)(表示正着的开头下标)+1==arr[i][j](长度)
if((len-j-1+arr[i][j]-1==i)&&arr[i][j]>maxlen) {
maxlen=arr[i][j];
startIndex=len-j-1;
}
}
}
return s.substring(startIndex,startIndex+maxlen);

方法二动态规划:将填表的过程记录下来而不是从头来

二维boolean[][]数组记录是某两位是不是回文串

选取[l,r],s[l]==s[r]之间的字符串如果他是回文串,则[l+1,r-1]也是回文串

//str[l,r] s[l]==s[r] 判断dp[l+1,r-1]是否为真
if(s.isEmpty()) {
return "";
}
int len=s.length();
int strLen=1;
int startIndex=0; boolean[][] dp=new boolean[len][len]; for(int r=0;r<len;r++) {
for(int l=0;l<r;l++) {
char left=s.charAt(l);
char right =s.charAt(r);
if(left==right&&((r-l<=2)||dp[l+1][r-1])) {
dp[l][r]=true;
if((r-l+1)>strLen) {
strLen=r-l+1;
startIndex=l;
}
}
}
}
return s.substring(startIndex,startIndex+strLen);

方法三:马拉车!!!神奇的马拉车算法!!!

核心思路:求出每个i对应的p[i]->找到最大的p[i]->求出下标和长度,截取返回

零、处理奇偶

在字符串头+"^",尾加+"$"

在每两个字符串之间+“#”

偶数->+头尾(偶数)->+奇数个间隔->奇数

奇数->+头尾(奇数)->+偶数个间隔->奇数

一、求出P[i]

中心扩展算法:从i开始向两边扩展比较,因为需要两个for循环所以空间复杂度约为O(n^2),为了减少中心扩展算法的时间复杂度,增加镜像法

镜像法:

C:回文串的中心

R:回文串的右边界

p[i]:i对应的回文串长度

i_mirror:i关于C对应的镜像

R>=i时,因为C是某个回文串的中心,二i又在此回文串右边界的左边,i可以用对应的i-mirror表示p[i]减少中心扩展算法的循环,使它变为某一常数即时间复杂度降为线性的了,注意当i+p[i_mirror]>R时,p[i_mirror]不一定是p[i],因为只有在R的范围里面它才是回文串,所以p[i]=min(R-i,i[i_mirror]),在这个的p[i]基础上再使用中心扩展算法时循环的就减少了

C和R的更新:因为要尽量少的使用中心扩展算法,尽量多的使用镜像法,需要将R尽量变大,但是一个确定回文串对应的p[i]是一定的,即R是一定的,只有将右边i+p[i]更大的R更新才能达到目的,所以只要出现新的R大于当前C对应的R就要更新

二 、找到最大下标和长度

因为p[i]是#改变后的,所以在原字符串中maxlen=p[i]max,对应的下标为 (C对应的i - maxLen) / 2

class Solution {
    public String longestPalindrome(String s) {
         String T = preProcess(s);
     int n = T.length();
     int[] P = new int[n];
     int C = 0, R = 0;
     for (int i = 1; i < n - 1; i++) {
         int i_mirror = 2 * C - i;
         if (R > =i) {
             P[i] = Math.min(R - i, P[i_mirror]);
         } 
         // 中心扩展算法对p[i]的更新
         while (T.charAt(i + 1 + P[i]) == T.charAt(i - 1 - P[i])) {
             P[i]++;
         }
         // 更新 C,R
         if (i +P[i] > R) {
             C = i;
             R = i + P[i];
         }
     }
     // 找出 P 的最大值
     int maxLen = 0;
     int centerIndex = 0;
     for (int i = 1; i < n - 1; i++) {
         if (P[i] > maxLen) {
             maxLen = P[i];
             centerIndex = i;
         }
     }
     int start = (centerIndex - maxLen) / 2; 
     return s.substring(start, start + maxLen);
    }
    public static String preProcess(String s) {
     int n = s.length();
     if (n == 0) {
         return "^$";
     }
     String ret = "^";
     for (int i = 0; i < n; i++)
         ret += "#" + s.charAt(i);
     ret += "#$";
     return ret;
 }
}

LeetCode最长回文子串的更多相关文章

  1. leetcode -- 最长回文子串

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

  2. [LeetCode]最长回文子串 java

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

  3. LeetCode.5-最长回文子串(Longest Palindromic Substring)

    这是悦乐书的第342次更新,第366篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Medium级别的第3题(顺位题号是5).给定一个字符串s,找到s中最长的回文子字符串. 您可以假设s ...

  4. 求最长回文子串 - leetcode 5. Longest Palindromic Substring

    写在前面:忍不住吐槽几句今天上海的天气,次奥,鞋子里都能养鱼了...裤子也全湿了,衣服也全湿了,关键是这天气还打空调,只能瑟瑟发抖祈祷不要感冒了.... 前后切了一百零几道leetcode的题(sol ...

  5. LeetCode之“字符串”:最长回文子串

    题目要求: 给出一个字符串(假设长度最长为1000),求出它的最长回文子串,你可以假定只有一个满足条件的最长回文串.例如,给出字符串 "abcdzdcab",它的最长回文子串为 & ...

  6. LeetCode(5):最长回文子串

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

  7. LeetCode:最长回文子串【5】

    LeetCode:最长回文子串[5] 题目描述 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为1000. 示例 1: 输入: "babad" 输出: ...

  8. LeetCode Golang 5. 最长回文子串

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

  9. 最长回文子串 C++实现 java实现 leetcode系列(五)

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

随机推荐

  1. HPU第一次团队赛

    D. Tom的战力问题 Tom被斯派克揍了TAT.Tom下定决心要战胜斯派克.但是在战胜最强的斯派克之前,Tom要先打败其他的狗.为此,他打算先收集一下信息.现在Tom在了得到了一些关于战斗力的小道消 ...

  2. 使用dynamic和MEF实现轻量级的AOP组件 (3)

    转摘 https://www.cnblogs.com/niceWk/archive/2010/07/22/1783068.html 水到渠成 在上一篇的<偷梁换柱>中,介绍了Weavabl ...

  3. Java中的二分查找

    二分查找:(折半查找) 前提:数组必须是有序的. 思想:每次都猜中间的那个元素,比较大或者小,就能减少一半的元素.思路:A:定义最小索引,最大索引. B:比较出中间索引 C:拿中间索引的值和要查找的元 ...

  4. 二分查找(通过相对位置判断区间位置)--17--二分--LeetCode33搜索旋转排序数组

    搜索旋转排序数组 假设按照升序排序的数组在预先未知的某个点上进行了旋转.( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] ). 搜索一个给定的目标值,如果数组中 ...

  5. Netty源码分析之ChannelPipeline—异常事件的传播

    ChannelHandler中异常的获取与处理是通过继承重写exceptionCaught方法来实现的,本篇文章我们对ChannelPipeline中exceptionCaught异常事件的传播进行梳 ...

  6. C#多线程(14):任务基础②

    目录 判断任务状态 再说父子任务 组合任务/延续任务 复杂的延续任务 并行(异步)处理任务 并行(同步)处理任务 并行任务的 Task.WhenAny 并行任务状态 循环中值变化问题 定时任务 Tas ...

  7. Thymeleaf入门入门入门入门入门入门入门入门入门入门入门

    Thymeleaf 官网部分翻译:反正就是各种好 Thymeleaf是用来开发Web和独立环境项目的服务器端的Java模版引擎 Spring官方支持的服务的渲染模板中,并不包含jsp.而是Thymel ...

  8. Scrapy中的crawlspider

    crawlspider 能自动的获取url并提交请求 命令:scrapy genspider -t crawl spidername 'example.cn' 所导入的模块 # -*- coding: ...

  9. 超详细步骤---Linux下的最新Git版本安装

    原文地址:https://blog.csdn.net/u010887744/article/details/53957613 [标注大头] 1.查看当前git版本:git --version 查看最新 ...

  10. How to permit SSH root Login in Ubuntu 18.04

    https://www.ubuntu18.com/ssh-permitrootlogin/ SSH root login is disabled by default in Ubuntu 18.04. ...