LeetCode 5 : Longest Palindromic Substring

题目描述

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.

Example 1:

Input: “babad”
Output: “bab”
Note: “aba” is also a valid answer.
Example 2:

Input: “cbbd”
Output: “bb”

方法与实现

方法1

思路:

动态规划 Dynamic Programming 来解,根 Palindrome Partitioning II 的解法很类似,
我们维护一个二维数组 dp,其中 dp[i][j] 表示字符串区间 [i, j] 是否为回文串,
当 i = j 时,说明只有一个字符,肯定是回文串,
当 i - j = 1,说明是相邻字符,此时需要判断 s[i] 是否等于 s[j],
当 i - j >= 2,说明i和j不相邻,即,除了判断 s[i] 和 s[j] 相等之外,还要判断dp[i + 1][j - 1] ,若为真,就是回文串,
通过以上分析,可以写出递推式如下:
在这里插入图片描述

实现

class Solution {
    public static String longestPalindrome(String s) {
        if (s.isEmpty())
            return "";
        int len_s = s.length();
        boolean dp[][] = new boolean[len_s][len_s];
        int left = 0, right = 0;
        int len = 0;//len记录回文串的最大长度
        for (int i = 0; i < len_s; ++i) {
            //当 i = j 时,说明只有一个字符,肯定是回文串,
            dp[i][i] = true;
            for (int j = 0; j < i; ++j) {
                //当 i - j < 1,说明是相邻字符,此时需要判断 s[i] 是否等于 s[j]
                //因为j<i 所以不存在i-j=0,i-j<2等价于i-j=1
                if (i - j < 2)
                    dp[j][i] = s.charAt(i) == s.charAt(j);
                    //当 i - j >= 2,说明i和j不相邻,即,除了判断 s[i] 和 s[j] 相等之外,还要判断dp[i + 1][j - 1] ,若为真,就是回文串,
                else
                    dp[j][i] = (s.charAt(i) == s.charAt(j)) && dp[j + 1][i - 1];

                //如果是回文串且长度大于len,则更新len
                if (dp[j][i] && len < i - j + 1) {
                    len = i - j + 1;//回文串长度
                    left = j;//回文串左边界
                    right = i;//回文串右边界
                }
            }
        }
        return s.substring(left, right + 1);
    }
}

方法2

思路:

以每一个字符为中心,像两边扩散来寻找回文串。
注意奇偶情况,由于回文串的长度可奇可偶,比如 “bob” 是奇数形式的回文,“noon” 就是偶数形式的回文,两种形式的回文都要搜索,对于奇数形式的,我们就从遍历到的位置为中心,向两边进行扩散,对于偶数情况,我们就把当前位置和下一个位置当作偶数行回文的最中间两个字符,然后向两边进行搜索。

实现

    class Solution {
    private int start, maxLen;
    public String longestPalindrome(String s) {
        int len=s.length();
        if(len<2)//长度为0或者1 肯定是回文序列
            return s;
        for (int i = 0; i < len-1; ++i){
            extendPalindrome(s, i, i);  //假设是基数长度
            extendPalindrome(s, i, i+1); //假设是偶数长度
        }
        return s.substring(start,start+maxLen);
        
    }
    
    
    private void extendPalindrome(String s, int j, int k) {
        while(j >= 0 && k<s.length()&& s.charAt(j)==s.charAt(k)){
            j--;//起始位置向前
            k++;//终止位置向后
        }
        if(maxLen<k-j+1-2){
            //jxxxk  j与k中间的为回文序列
            start=j+1;//更新起始位置
            maxLen=k-j+1-2;//更新长度  
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值