最大回文子串

5. 最长回文子串

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

示例 1:

输入: "babad"
输出: "bab"
注意: "aba"也是一个有效答案。

示例 2:

输入: "cbbd"
输出: "bb"

Manacher算法

class Solution {
    public static String longestPalindrome(String s) {
        if(s == null || s.length() < 1)
            return "";
        String str = dealWithS(s);  // 处理一下s,即将给字符串s的中间加上特殊字符,这样无论对于奇数字符还是偶数字符可以做同样的处理
        int[] res = new int[str.length()];
        int R = 0; // 当前所能扩展的半径
        int C = 0; // C位置的半径为R
        int maxC= 0; // 最长的半径的位置
        res[0] = 0;
        for(int i = 1; i < str.length(); i++)
        {
            int j = 2 * C - i;  // i点的对称点
            if(j >= 0 && res[j] < R - i)  // 对称点存在且对称点的回文半径在C的回文中
            {
                res[i] = res[j];
            }
            else  // 否则,需要根据i点一点一点的计算
            {
                int k = 1;
                while(R + k < str.length() && 2 * i - R - k >= 0)
                {
                    if(str.charAt(R + k) == str.charAt(2 * i - R - k))
                        k ++;
                    else
                        break;
                }
                res[i] = R -i + k - 1;
                if(res[i] + i > R)
                {
                    R = res[i] + i;
                    C = i;
                }
            }

            maxC = res[maxC] > res[i] ? maxC : i;  // maxC保存的是回文半径最大的那个点的位置
        }
        String subStr = str.substring(maxC - res[maxC], maxC + res[maxC] + 1);
        StringBuffer sb = new StringBuffer();
        for(int i = 0; i < subStr.length(); i++)
        {
            if(subStr.charAt(i) != '#')
                sb.append(subStr.charAt(i));
        }
        return sb.toString();
    }
    public static String dealWithS(String s)  // 将原字符串进行处理
    {
        StringBuffer sb = new StringBuffer();
        sb.append("#");
        for(int i = 0; i < s.length (); i++)
        {
            sb.append(s.charAt(i));
            sb.append("#");
        }
        return sb.toString();
    }
}

方法二:


class Solution {
    public String longestPalindrome(String s) {
       if(s.length()<=1) return  s;  
        char[] characters = s.toCharArray();  
        //用于存放str中最长回文子串所对应的下标  
        int[] range = {0,1};  
        for(int i = 0;i<characters.length;i++){  
            i = helper(i,characters,range);  
        }  
        return s.substring(range[0],range[1]);  
    }  
  
    private int helper(int index,char[] c,int[] range) {  
        int low = index;  
        int high = index;  
        //如果遇到相同字符,则high进位,如abba ,这样偶回文子串也可以当做奇回文处理了  
        while(high<c.length-1 && c[high]==c[high+1]){  
            high++;  
        }  
        int cursor = high;  
  
        while(high+1<c.length&&low-1>=0&&c[low-1]==c[high+1]){  
            low--;  
            high++;  
        }  
        if(high-low+1>range[1]-range[0]){  
            range[0] = low;  
            range[1] = high + 1;  
        }  
        return cursor;  
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值