Leetcode 5. Longest Palindromic Substring(java版)

题目:

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

题目大意:

给一个字符串,求这个字符串中最长的回文字串。

example1:

Input: “babad”

Output: “bab”

Note: “aba” is also a valid answer.

example2:

Input: “cbbd”

Output: “bb”

思路 1:

我最先想到的是暴力法,结果超时了。

代码1:

class Solution {
    public boolean Judge(String s) {
        int i = 0 , j = s.length()-1;
        while(i <= j) {
            if(s.charAt(i) == s.charAt(j)) {
                i++;
                j--;
            }
            else
                break;
        }
        if(i <= j) return false;
        return true;
    }
    public String longestPalindrome(String s) {
        int i = 0;
        int j = 0;
        int n = s.length();
        String ans ="" , tempans = "";
        int temp = 0;
        for(i=0 ; i < n ; i++) {
            for(j=i+1 ; j <= n ; j++) {
                tempans = s.substring(i , j);
                if(Judge(tempans)) {
                    if(tempans.length() > temp) {
                        temp = tempans.length();
                        ans = tempans;
                    }
                }
            }
        }
        return ans;
    }
}

思路二:

假设dp[ i ][ j ]的值为true,表示字符串s中下标从 i 到 j 的字符组成的子串是回文串。那么可以推出:
dp[ i ][ j ] = dp[ i + 1][ j - 1] && s[ i ] == s[ j ]。
这是一般的情况,由于需要依靠i+1, j -1,所以有可能 i + 1 = j -1, i +1 = (j - 1) -1,因此需要求出基准情况才能套用以上的公式:
a. i + 1 = j -1,即回文长度为1时,dp[ i ][ i ] = true;
b. i +1 = (j - 1) -1,即回文长度为2时,dp[ i ][ i + 1] = (s[ i ] == s[ i + 1])。
有了以上分析就可以写出代码了。需要注意的是动态规划需要额外的O(n2)的空间。

代码二:

class Solution {
    public String longestPalindrome(String s) {
        if(s == null) return null;
        int n = s.length();
        if(n == 1) return s;
        int i = 0 , j = 0;
        int maxlen = 1 , begin = 0;
        String ans = null;
        boolean[][] dp = new boolean[1010][1010];
        for(i=0 ; i < n ; i++) {
            dp[i][i] = true;
        }
        for(i = 0 ; i < n-1 ; i++) {
            if(s.charAt(i) == s.charAt(i+1)) {
                dp[i][i+1] = true;
                begin = i;
                maxlen = 2;
            }
        }
        for(i = 3 ; i <= n ; i++) {
            for(j=0 ; j < n - i + 1 ; j++) {
                int m = j + i - 1;
                if(dp[j+1][m-1] && s.charAt(j) == s.charAt(m)) {
                    dp[j][m] = true;
                    begin = j;
                    maxlen = i;
                }
            }
        }
        return s.substring(begin , begin + maxlen);
    }
}

思路三:

回文字符串显然有个特征是沿着中心那个字符轴对称。比如aha沿着中间的h轴对称,a沿着中间的a轴对称。那么aa呢?沿着中间的空字符”轴对称。
所以对于长度为奇数的回文字符串,它沿着中心字符轴对称,对于长度为偶数的回文字符串,它沿着中心的空字符轴对称。
对于长度为N的候选字符串,我们需要在每一个可能的中心点进行检测以判断是否构成回文字符串,这样的中心点一共有2N-1个(2N-1=N-1 + N)。

代码三:

class Solution {
    public String longestPalindrome(String s) {
        if(s == null) return null;
        int n = s.length();
        if(n == 1) return s;
        int maxlen = 0 , begin = 0;
        int i = 0 , j = 0;
        for(i=1 ; i < n ; i++) {
            int low = i-1 , high = i;
            while(low >= 0 && high < n && s.charAt(low) == s.charAt(high)) {
                low--;
                high++;
            }
            if(high - low -1 > maxlen) {
                maxlen = high - low -1;
                begin = low + 1;
            }
            low = i - 1; high = i + 1;
            while(low >= 0 && high < n && s.charAt(low) == s.charAt(high)) {
                low--;
                high++;
            }
            if(high - low -1 > maxlen) {
                maxlen = high - low -1;
                begin = low + 1;
            }
        }
        return s.substring(begin , begin + maxlen);
    }
}

你可能感兴趣的:(Leetcode)