求解最长的回文子串

原创 2018年04月16日 11:20:05

1.暴力法

找出所有子串,并且判断是否是回文子串,并且记录最长长度,算法复杂度为O(n^3),强烈不推荐。

2.对称求解法

遍历字符串每个位置,从每个位置向两边扩散,判断是否对称,算法复杂度为O(n^2),但是需要考虑长度为奇偶两种情况。

示例代码:

 public int longestPalindrome(String str) {
int length=str.length();
if(str==null||length<1) {
return 0;
}
int result=0;
int max=0;
//遍历所有位置
for(int i=0;i<length;i++) {
//考虑str长度为奇数的情况,j为两边移动的距离
for(int j=0;j<=i&&i+j<length;j++) {
if(str.charAt(i-j)!=str.charAt(i+j)) {
break;
}
max=j*2+1;
}
if(max>result) {
result=max;
}
//考虑str长度为偶数的情况,j为移动的距离
for(int j=0;j<=i&&i+j+1<length;j++) {
if(str.charAt(i-j)!=str.charAt(i+j+1)) {
break;
}
max=j*2+2;
}
if(max>result)
result=max;
}
return result;

}

3.Manacher算法

从解法2我们可以发现仍有很多子串被重复判断,所以就引入了Manacher算法。

第一个不同:首先Manacher算法为了解决奇偶问题在原字符串中插入了#符号,将字符串长度统一为奇数,例如将字符串abcbae扩充为#a#b#c#b#a#e#

第二个不同:Manacher算法引入了一个回文半径,即用一个数组保存每个字符的回文半径,回文半径初始化为1,(本身),求解回文半径方法见代码注释。

 public  int longestPalindrome(String str) {
    //扩充字符串
    StringBuilder str2 = new StringBuilder();
    str2.append('#');
    for (int i = 0; i < str.length(); i ++) {
        str2.append(str.charAt(i));
        str2.append('#');
    }
    //回文半径数组
    int [] rad = new int[str2.length()];
    // right表示已知的最长回文子串最右边缘坐标
    int right = -1;
    // center表示已知的最长回文子串中点坐标
    int center = -1;
    
    for (int i = 0; i < str2.length(); i ++) {
        //初始回文半径1,自己本身
        int r = 1;
        // 找到i的关于center对称位置j,j=2*center-i
        //如果对称位置的rad小于right-i,说明以j为中心的回文子串在已知最长回文子串中,由对称性可知,rad[i]=rad[j]
        //否则i的回文半径就是right-i,所以回文半径就是right-i,所以就相当于取两个的最小值,这种情况就需要再向两边进行匹配
        //进行这个判断的原因是为了省去重复字符串扫描
        if (i <= right) {
            r = Math.min(right-i, rad[2 * center - i]);
        }
        // 向两边进行匹配
        while (i - r >= 0 && i + r < str2.length() && str2.charAt(i - r) == str2.charAt(i + r)) {
            r++;
        }
        // 如果扫描结束后位置大于right,需要更新right和center
        if (i + r - 1> right) {
            right = i + r - 1;
            center = i;
        }
        rad[i] = r;
    }
    
    // 扫描最大长度
    int result = 0;
    for (int r : rad) {
        if (r > result) {
            result = r;
        }
    }
    return result - 1;
}

C语言及程序设计进阶

-
  • 1970年01月01日 08:00

2016 腾讯笔试题 最长回文字串(不连续)(dp)

最长回文字串 一个字符串有许多子序列,比如字符串abcfgbda,它的子序列有a、bfg、bfgbd,在这些子序列中肯定有回文字符串。现在要对任意 字符串求其最长的回文子序列。注意,本文不是解决最长回...
  • piaocoder
  • piaocoder
  • 2016-04-05 18:40:58
  • 1356

算法竞赛入门经典 3.3 最长回文子串

//例题3-4 /* * 输入一个字符串,求出其中最长的回文子串。子串的含义是:在原串中连续出现的字符串片段。 *回文的含义是:正看着和倒看着相同,如abba和yyxyy。在判断时,应该忽略所有标点...
  • wwj_748
  • wwj_748
  • 2012-04-05 18:31:22
  • 2182

给定一个字符串s,找出s中最长的回文子串,你可以假设s的最大长度是1000。

找出一个字符串中最大的回文字符串 思路:从第一个字符串开始,一次向左向右判断,如果相同就继续向左向右直到不相同或者越界为止,并判断最大长度,依次更新最大长度值,并记录最大长度值的开始为止。示例代码如...
  • qq297877375
  • qq297877375
  • 2018-01-25 23:23:50
  • 338

【最长回文子串】Manache算法,O(N)时间复杂度

找一个字符串里的最长回文子串。 暴力法:定中心,从0长度向两端扩展的方法O(n^2), n >= 10^5还是超时,故只能《O(n^2) Manacher's 算法:定中心,从p[r],(已能确定...
  • zhong123123123
  • zhong123123123
  • 2016-05-06 11:15:27
  • 1192

leetcode最长回文字符串_动态规划

1、问题描述给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 长度最长为1000。示例:输入: &quot;babad&quot; 输出: &quot;bab&quot; 注意: &...
  • qq_34266990
  • qq_34266990
  • 2018-03-29 22:16:01
  • 12

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

题目描述       给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 长度最长为1000。       回文串是指正读和反读都一样的字符串。解题思路及实现方法一:最长公共子串     ...
  • Regemc
  • Regemc
  • 2018-03-26 09:51:29
  • 26

Leetcode005--字符串中最大的回文子串

给定一个字符串S,找出它的最大的回文子串,你可以假设字符串的最大长度是1000,而且存在唯一的最长回文子串...
  • jinhuoxingkong
  • jinhuoxingkong
  • 2016-09-25 13:48:38
  • 627

LeetCode OJ 之 Longest Palindromic Substring (最长回文子串)

题目: Given a string S, find the longest palindromic substring in S. You may assume that the maximum...
  • u012243115
  • u012243115
  • 2014-12-10 22:16:42
  • 791

腾讯2016软开实习生笔试题-编程2:最大回文子串长度

笔试编程第2题是一个字符串题,要求给定字符串最大长度的子串,思路也很明了。我是使用的带备忘录的递归方法(recursion with memorization)。 问题:求给定字符串s的回文(pa...
  • yc461515457
  • yc461515457
  • 2016-04-05 10:53:21
  • 884
收藏助手
不良信息举报
您举报文章:求解最长的回文子串
举报原因:
原因补充:

(最多只允许输入30个字)