Longest Palindromic Substring

Given a string S, find the longest palindromic substring in S. You may assume that the maximum length ofS is 1000, and there exists one unique longest palindromic substring.

思路:Palindrome分奇数和偶数个,像aba, abba。这里的方法叫做中间生长法,从中间开始,i,j向两边扩展,如果相同继续,否则return,这样来算,O(n^2)的复杂度。

2N-1个center。为什么有2n-1个中心,是因为,每个字符可以做中心,这个没什么问题,那么abba的中心就是两个b之间的空字符串,这样当你生长的时候,要以bb为起点开始两边生长,这样的话,每次都以空字符串生长,这样是n-1个。

注意最后需要用s.substring(start+1,end),因为循环最后已经对start和end进行了--和++的操作。

找中心点的操作就是:扫两遍,分别以 (i,i)  (i,i+1)为左右指针,开始扫描,找对称的string,然后更新。

class Solution {
    public String longestPalindrome(String s) {
        if(s == null || s.length() == 0) {
            return s;
        }
        // odd, even;
        String longest = "";
        for(int i = 0; i < s.length(); i++) {
            String oddstr = findPalindrome(s, i, i);
            if(oddstr.length() > longest.length()) {
                longest = oddstr;
            }
            
            String evenstr = findPalindrome(s, i, i + 1);
            if(evenstr.length() > longest.length()) {
                longest = evenstr;
            }
        }
        return longest;
    }
    
    private String findPalindrome(String s, int i, int j) {
        while(0 <= i && j < s.length()) {
            if(s.charAt(i) == s.charAt(j)) {
                i--;
                j++;
            } else {
                break;
            }
        }
        return s.substring(i + 1, j);
    }
}

此题同时可以用dp来做。我觉得此题的突破点就在于dp的矩阵表示的物理意义是什么。这点抓住了,其实这题就出来了。

dp[i][j] 表示的物理意义是:string s里面i到j之间的string是否是palindrome. 那么很自然的会推导出递推关系:

if s(i) != s(j) 直接 dp[i][j] = false;

if s(i) == s(j)  : 

      if( j-i<=2) dp[i][j] = true; // aba, 这个是容易犯错的点。 j-i = 2的情况一定要考虑进去;

      else dp[i][j] = dp[i+1][j-1]  代表i,j指针向中间移动;

因为计算dp[i][j] 需要用到下一层的dp[i+1][j-1],所以for循环的时候,要从下开始算,也就是从后面开始计算;

class Solution {
    public String longestPalindrome(String s) {
        int n = s.length();
        boolean[][] dp = new boolean[n][n];
        String maxstr = "";
        for(int i = 0; i < n; i++) {
            dp[i][i] = true;
            maxstr = s.substring(i, i + 1);
        }
        
        char[] ss = s.toCharArray();
        // 先算小的区间,然后算大的区间;
        for(int len = 2; len <= n; len++) {
            for(int i = 0; i + len - 1 < n; i++) {
                int j = i + len - 1;
                if(ss[i] != ss[j]) {
                    dp[i][j] = false;
                } else {
                    // ss[i] == ss[j];
                    if(j - i <= 1) {
                        dp[i][j] = true;
                    } else {
                        dp[i][j] = dp[i + 1][j - 1];
                    }
                    if(dp[i][j]) {
                        if(j - i + 1 > maxstr.length()) {
                            maxstr = s.substring(i, j + 1);
                        }
                    }
                }
            }
        }
        return maxstr;
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值