最长回文子串

leetcode 5.最长回文子串

头一次拿Java写算法题

经典的马拉车算法
class Solution
{
    public String longestPalindrome(String s)
    {
        //每个空位插入#,以排除对奇偶性的判断
        StringBuffer buffer = new StringBuffer();
        buffer.append('#');
        for (int i = 0; i < s.length(); i++)
        {
            buffer.append(s.charAt(i));
            buffer.append('#');
        }
        String string = new String(buffer);


        //开始计算
        int[] RL = new int[string.length() + 1];
        RL[0] = 1;

        int maxRight = 0; //所有回文子串,能达到的最右一个字符的位置
        int pos = 0;      //该回文子串对应的对称轴

        //从第二个字符开始遍历
        for (int i = 1; i < string.length(); i++)
        {
            //i在maxRight右边。。。直接扩展
            if (i > maxRight)
            {
                //由中心向两侧扩展的算法
                int left = i;
                int right = i;
                while (left >= 0 && right < string.length() && string.charAt(left) == string.charAt(right))
                {
                    left--;
                    right++;
                }
                left++;
                right--;
                //更新RL
                RL[i] = right - i + 1;
                //更新maxRight和pos
                maxRight = right;
                pos = i;
            } else  //i在左边时。。重点
            {
                //当i关于pos的对称点的RL大于pos所在串的半径时。。已maxright-i为已知半径扩展
                int posR = maxRight - pos;
                int R = RL[2 * pos - i];
                if (R > posR)
                {
                    int left = 2 * i - maxRight;
                    int right = maxRight;
                    while (left >= 0 && right < string.length() && string.charAt(left) == string.charAt(right))
                    {
                        left--;
                        right++;
                    }
                    left++;
                    right--;
                    //更新RL
                    RL[i] = right - i + 1;
                    //更新maxRight和pos
                    maxRight = right;
                    pos = i;
                } else   //小于时
                {
                    int left = i - R;
                    int right = i + R;
                    while (left >= 0 && right < string.length() && string.charAt(left) == string.charAt(right))
                    {
                        left--;
                        right++;
                    }
                    left++;
                    right--;
                    //更新RL
                    RL[i] = right - i + 1;
                    //更新maxRight和pos
                    if (right > maxRight)
                    {
                        maxRight = right;
                        pos = i;
                    }
                }

            }
        }
        //获取结果
        int num = 0;
        int p = 0;
        for (int i = 0; i < RL.length; i++)
        {
            if (RL[i] > num)
            {
                num = RL[i];
                p = i;
            }
        }
        num--;
        String result = string.substring(p - num, p + num);
        StringBuffer b = new StringBuffer();
        for (int i = 0; i < result.length(); i++)
        {
            if (result.charAt(i) != '#')
            {
                b.append(result.charAt(i));
            }
        }
        return b.toString();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值