1. 程式人生 > 實用技巧 >leetcode 5.最長迴文子串

leetcode 5.最長迴文子串

package com.example.lettcode.dynamicprogramming;

import java.util.Arrays;

/**
 * @Class LongestPalindrome
 * @Description 5 最長迴文子串
 * 給定一個字串 s,找到 s 中最長的迴文子串。你可以假設 s 的最大長度為 1000。
 * <p>
 * 示例 1:
 * 輸入: "babad"
 * 輸出: "bab"
 * 注意: "aba" 也是一個有效答案。
 * <p>
 * 示例 2:
 * 輸入: "cbbd"
 * 輸出: "bb"
 * @Author
 * @Date 2020/8/5
 **/
public class LongestPalindrome {
    /**
     * 動態規劃: 解法和leetcode 647 迴文子串 類似
     * (1)dp[i][j]表示從s[i..j]是否為迴文子串
     * (2)狀態轉換:
     *      i:當j-i<3 並且s[i]=s[j]時,即類似abs時,也是迴文串
     *      ii: 當s[i]=s[j]並且s[i+1...j-1]是迴文串時,s[i...j]是迴文串
     */
    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);
    }

    public static void main(String[] args) {
        String s = "babad";
        String ans = longestPalindrome(s);
        System.out.println("LongestPalindrome demo01 resul:" + ans);

        s = "cbbd";
        ans = longestPalindrome(s);
        System.out.println("LongestPalindrome demo02 resul:" + ans);
    }
}