查找最长回文子串--Longest Palindromic Substing(java实现时间复杂度O(n))

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/smileiam/article/details/86548457

LeetCode 5:Longest Palindromic Substing

题目:寻找最长回文子串

描述:

给定一个字符串s,在s中找到最长的回文子中,假设s的最大长度为1000

如输入"babad" ,输出"bab"工或是"aba"都算正确结果。

输入"cbbd",输入"bb"

思路:

遍历字符串中的每一个字符m,再查找该字符m前后的字符是否相等,记录前L、后R的位置,R-L-1就是字符m所能构成回文子串的最大长度。但有一点需要注意,如果字符m和它的后一个字符串相等,也可以构成回文串。所以如果两者都满足即出现“***ccc***”(***代表省略的字符串)这种情况,则需要计算两种情况下的回文子串,比较它们的大小。

class Solution {
    public String longestPalindrome(String s) {
        if(s == null || s.length() <= 1) return s;//边界判断,当s为空或是只有一个字符"a"时(一个字符也算回文)返回它本身
        int length = s.length();
        int start = 1, left = start, right = start;
        String longestParlind = ""+s.charAt(0);//当字符串中每个字符各不相同,则返回第一个字符,即"abcdefg",它的最长回文子串是"a"
        int len1 = 0, len2 = 0;//分别记录上面说的两种情况,一个是"**aba**"这种,中间和左右不同,一个是"**aa**"这种情况,中间和左或是右相同
        while(start < length) {
            if((start+1) < length && s.charAt(start-1) == s.charAt(start+1)) {//当前字符的左右字符相同时,计算回文长度
                len1 = parlindLength(s, start-1, start+1);
            } 
            if(s.charAt(start-1) == s.charAt(start)) {//当前字符和前一个字符相同时,计算回文长度
                 len2 = parlindLength(s, start-1, start);
            } 
            int len = Math.max(len1, len2);
            if(len > longestParlind.length()) {//取出最长的回文子串,这里当然可以优化, 只记录最长回文子串的start\end位置,最后再调用s.substring方法
                longestParlind = s.substring(start-len/2, start+(len+1)/2);
            }
            start++;
            
        }
        return longestParlind;
    }
    
//计算字符在start位置回文子串的长度
    private int parlindLength(String s, int left, int right) {
        int L = left - 1, R = right + 1;
        while(L >= 0 && R < s.length() && s.charAt(L) == s.charAt(R)) {
            L--;
            R++;
        }
        return R-L-1;
    }
}

此解法,时间复杂度为O(n),比暴力解法O(n^2)更优。空间复杂度为常数。

猜你喜欢

转载自blog.csdn.net/smileiam/article/details/86548457