lintcode -- 最长回文子串

来源:互联网 发布:python idle for mac 编辑:程序博客网 时间:2024/05/17 09:04

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

样例

给出字符串 "abcdzdcab",它的最长回文子串为 "cdzdc"






    /**
     * @param s input string
     * @return the longest palindromic substring
     * 
1、暴力法
最容易想到的就是暴力破解,求出每一个子串,之后判断是不是回文,找到最长的那个。
求每一个子串时间复杂度O(N^2),判断子串是不是回文O(N),两者是相乘关系,所以时间复杂度为O(N^3)。
2、动态规划
回文字符串的子串也是回文,
比如P[i,j](表示以i开始以j结束的子串)是回文字符串,
那么P[i+1,j-1]也是回文字符串。这样最长回文子串就能分解成一系列子问题了。
这样需要额外的空间O(N^2),算法复杂度也是O(N^2)。


3、中心扩展
中心扩展就是把给定的字符串的每一个字母当做中心,向两边扩展,
这样来找最长的子回文串。算法复杂度为O(N^2)。
但是要考虑两种情况:
1、像aba,这样长度为奇数。
2、想abba,这样长度为偶数。




 题意为求最长回文子串, 直接枚举子串首尾位置再判断是否会问,时间复杂度为O(N^3),
    换个思路,枚举回文串的对称中心位置,向两侧扫描检测最长回文长度时间复杂度为O(N^2)
    对于最长回文子串问题有对应O(N)算法--Manacher算法
    笔者觉得面试中应当不会有这么高的要求,有兴趣可以自行了解该算法
// 将原字符串扩展成#a#b#的形式可以直接枚举长度,不用考虑回文串长度的奇偶性
     */
 
public class Solution {
    public String longestPalindrome(String s) {
        if (s == null || s.length() == 0) return "";
        int length = s.length(); 
        int max = 0;
        String result = "";
        //!!需要2*length
        for(int i = 1; i <= 2 * length - 1; i++){
            //计数得设置在循环里面
            int count = 1;
            while(i - count >= 0 && i + count <= 2 * length  
                    && get(s, i - count) == get(s, i + count)){
                count++;
            }
            count--; // there will be one extra count for the outbound #
            if(count > max) {
                //最长则求出子串
                result = s.substring((i - count) / 2, (i + count) / 2);
                max = count;
            }
        }
        return result;
    }
    private char get(String s, int i) {
        //下标为偶数,则变成#  a#b#b#a#
        if(i % 2 == 0)
            return '#';
        else 
            return s.charAt(i / 2);
    }
}

原创粉丝点击