常見DP問題匯總


注:本文目前只提供速記,不提供詳解。

1. 5. 最長回文子串[五星]

狀態:
令 dp[i][j] 表示子數組 s[i...j] 是否為回文子串。初始化 dp[i][i] = true,並且 dp[i][i+1] = (s[i]==s[i+1])。
狀態轉移方程:

\[dp[i][j] = dp[i+1][j-1] \&\& s[i] == s[j] \]

代碼:

// 時間復雜度:O(n^2)
// 空間復雜度:O(n^2)
class Solution {
    public String longestPalindrome(String s) {
        if(s.length() == 0) return "";
        boolean[][] dp = new boolean[s.length()][s.length()];
        // 初始化
        int begin = 0, end = 0;
        for(int i = 0; i < s.length(); i++) {
            dp[i][i] = true;
            if(i < s.length()-1) {
                dp[i][i+1] = s.charAt(i) == s.charAt(i+1);
                if(dp[i][i+1] && end - begin < 1) {
                    begin = i;
                    end = i + 1;
                }
            }
        }
        // 狀態轉移
        for(int len = 2; len < s.length(); len++) {
            for(int i = 0; i + len < s.length(); i++) {
                int j = i + len;
                dp[i][j] = dp[i+1][j-1] && s.charAt(i) == s.charAt(j);
                if(dp[i][j] && end - begin < j - i) {
                    begin = i;
                    end = j;
                }
            }
        }
        return s.substring(begin, end+1);
    }
}

2. 516. 最長回文子序列 [五星]

概念說明:

注意子串(substring)和子序列(subsequence)的區別,子串(substring)要求連續,子序列(subsequence)不要求連續

狀態:
令 dp[i][j] 表示 s[i...j] 中最長回文子序列的長度,初始化 dp[i][i] = 1。
狀態轉移方程:

\[dp[i][j] = \begin {cases} dp[i+1][j-1] + 2 & s[i] == s[j] \\ max(dp[i+1][j],dp[i][j-1]) & s[i] != s[j]\\ \end {cases} \]

代碼:

// 時間復雜度:O(n^2)
// 空間復雜度:O(n^2)
class Solution {
    public int longestPalindromeSubseq(String s) {
        int n = s.length();
        if(n == 0) return 0;

        int[][] dp = new int[n][n];
        // 初始化
        for(int i = 0; i < n; i++) {
            dp[i][i] = 1;
        }
        // 狀態轉移
        for(int i = n-2; i >= 0; i--) {
            for(int j = i+1; j < n; j++) {
                if(s.charAt(i) == s.charAt(j)) {
                    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];
    }
}

3、300. Longest Increasing Subsequence [五星]
4. 1143. Longest Common Subsequence [五星]
5. 10. Regular Expression Matching [五星+++]
6. 44. Wildcard Matching [五星+++]
7. 53. Maximum Subarray [五星]
8. 152. Maximum Product Subarray [五星++]
9. 62. Unique Paths
10. 63. Unique Paths II
11. 64. Minimum Path Sum [和62題是一樣的]
12. 174. Dungeon Game
13. 741. Cherry Pickup [round trip, 暫時放棄...]
14. 120. Triangle [第64題的變形, 自底向上/自頂向下]
15. 509. Fibonacci Number
16. 70. Climbing Stairs
17. 746. Min Cost Climbing Stairs
18. 84. Largest Rectangle in Histogram [這一題不屬於dp問題, 但是和85題是強相關的]
19. 85. Maximal Rectangle [五星++, 84題的follow-up]
20. 221. Maximal Square
21. 32. Longest Valid Parentheses [這一題比較獨立, 五星++]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM