1. 程式人生 > 其它 >LeetCode 516 最長迴文子序列 + 5 最長迴文子串

LeetCode 516 最長迴文子序列 + 5 最長迴文子串

516 最長迴文子序列

給你一個字串 s ,找出其中最長的迴文子序列,並返回該序列的長度。

子序列定義為:不改變剩餘字元順序的情況下,刪除某些字元或者不刪除任何字元形成的一個序列。

示例 1:

輸入:s = "bbbab"
輸出:4
解釋:一個可能的最長迴文子序列為 "bbbb" 。

示例 2:

輸入:s = "cbbd"
輸出:2
解釋:一個可能的最長迴文子序列為 "bb" 。
動態規劃
/**
 * DP
 *
 * @param s
 * @return
 */
public static int longestPalindromeSubseq(String s) {
    if (s.length() == 0) return 0;

    int n = s.length();
    // dp[i][j] 表示從i到j的子序列的最長迴文長度
    int[][] dp = new int[n][n];
    for (int i = n - 1; i >= 0; i--) {
        dp[i][i] = 1;
        char ch1 = s.charAt(i);
        for (int j = i + 1; j < n; j++) {
            char ch2 = s.charAt(j);
            // 如果S[i]==S[j] 表示i~j的迴文長度為i+1~j-1的範圍內的長度
            if (ch1 == ch2) {
                dp[i][j] = dp[i + 1][j - 1] + 2;
            } else {
                dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]);
            }
        }
    }
    return dp[0][n - 1];
}

5 最長迴文子串

給你一個字串 s,找到 s 中最長的迴文子串。

示例 1:

輸入:s = "babad"
輸出:"bab"
解釋:"aba" 同樣是符合題意的答案。

示例 2:

輸入:s = "cbbd"
輸出:"bb"

示例 3:

輸入:s = "a"
輸出:"a"

示例 4:

輸入:s = "ac"
輸出:"a"
動態規劃
public static String longestPalindrome(String s) {
    if (s == null || s.length() == 0) return "";
    boolean[][] dp = new boolean[s.length()][s.length()];
    int start = 0, end = 0;
    for (int i = 0; i < s.length(); i++) {
        for (int j = 0; j < s.length(); j++) {
            dp[i][j] = false;
        }
        dp[i][i] = true;
    }
    for (int i = s.length() - 2; i >= 0; i--) {
        for (int j = i + 1; j < s.length(); j++) {
            dp[i][j] = s.charAt(i) == s.charAt(j)
                    //小於3是因為aba一定是迴文
                    && (j - i < 3 || dp[i + 1][j - 1] == true);
            // dp[i][j]為True,並且需要更新的話
            if (dp[i][j] && end - start < j - i) {
                end = j;
                start = i;
            }
        }
    }
    return s.substring(start, end + 1);
}