5. Longest Palindromic Substring

题目

Example 1:

Input: s = "babad"
Output: "bab"
Note: "aba" is also a valid answer.

Example 2:

Input: s = "cbbd"
Output: "bb"

Example 3:

Input: s = "a"
Output: "a"

Example 4:

Input: s = "ac"
Output: "a"

Constraints:

  • 1 <= s.length <= 1000
  • s consist of only digits and English letters (lower-case and/or upper-case)

解法一

思路是从头开始遍历该字符串,看每一个字符串向前后扩展,所能形成的最长回文字符串长度是多少。有一点麻烦的是回文串有两种,一种是奇数的(aba),一种是偶数的(abba)。这两种情况要分别考虑。我自己的代码也是这种思路做的,有点啰嗦,把高赞评论里的贴出来。

public class Solution {
private int lo, maxLen;

public String longestPalindrome(String s) {
	int len = s.length();
	if (len < 2)
		return s;
	
    for (int i = 0; i < len-1; i++) {
     	extendPalindrome(s, i, i);  //assume odd length, try to extend Palindrome as possible
     	extendPalindrome(s, i, i+1); //assume even length.
    }
    return s.substring(lo, lo + 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) {
		lo = j + 1;
		maxLen = k - j - 1;
	}
}}

解法二:

另一种思路有点类似递归,就是如果字符串***是回文字符串,意味着首尾各加上一个相同字符后也是递归,对应奇数个数的回文串。或者两位长度的子字符串,且这两位字符相同,则为递归,且按照首尾各加一个相同字符的方式扩展后也是递归,对应偶数个数的回文串。

如下解法中i代表子字符串左起点;j代表子字符串右起点。

class Solution {
  
    public String longestPalindrome(String s) {
        if (s == null || s.length() <= 1)
            return s;
        int len = s.length();
        // dp[i][j] stands for status of a substring starting at i and ending at j incl j
        boolean[][] dp = new boolean[len][len];
        
        // initialize all the 1 character palins
        for(int i = 0; i < len; i++)
            dp[i][i] = true;
        
        // to compute dp[i][j] we need dp[i+1][j-1]
        // so the i - outer loop needs to go from higher to lower
        // and the j - inner loop needs to go from lower to higher
        int maxLen = 0, maxSta = 0, maxEnd = 0;
        for(int i = len; i >= 0; i--){
            // dist of 0 - already covered by initialization
            for(int dist = 1; dist < len - i; dist++){
                int j = i + dist;
                // we are ready to compute dp [i] [j]
                if (dist == 1 && s.charAt(i) == s.charAt(j)){
                    dp[i][j] = true;
                } else if (s.charAt(i) == s.charAt(j)){
                    dp[i][j] = dp[i+1][j-1];
                }
                // if true
                if (dp[i][j] && maxLen < (j-i+1)){
                    maxLen = j - i + 1;
                    maxSta = i;
                    maxEnd = j;
                }
            }
        }
        return s.substring(maxSta,maxEnd+1);
    }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值