动态规划

Matrix DP

1 Triangle

    public int minimumTotal(int[][] triangle)
    {
        if (triangle == null || triangle.length == 0) {
            return 0;
        }
        
        if (triangle.length == 1) {
            return triangle[0][0];
        }
        
        int length = triangle.length;
        int[] num = new int[length];
        for (int i = 0; i < length; i++) {
            num[i] = triangle[length - 1][i];
        }
        
        for (int i = length - 2; i >= 0; i--) {
            for (int j = 0; j <= i; j++) {
                num[j] = Math.min(num[j], num[j + 1]) + triangle[i][j];
            }
        }
        
        return num[0];
    }
View Code

2 Minimum Path Sum

    public int minPathSum(int[][] grid)
    {
        if (grid == null || grid.length == 0 || grid[0].length == 0) {
            return 0;
        }
        int m = grid.length;
        int n = grid[0].length;
        
        int[][] sum = new int[m][n];
        sum[0][0] = grid[0][0];
        
        for (int i = 1; i < n; i++) {
            sum[0][i] = sum[0][i - 1] + grid[0][i];
        }
        
        for (int i = 1; i < m; i++) {
            sum[i][0] = sum[i - 1][0] + grid[i][0];
        }
        
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                sum[i][j] = Math.min(sum[i - 1][j], sum[i][j - 1]) + grid[i][j];
            }
        }
        return sum[m - 1][n - 1];
    }
View Code

3 Unique Paths

    public int uniquePaths(int m, int n) 
    {  
        if (m < 0 || n < 0) {
            return 0;
        }
        
        int[][] sum = new int[m][n];
        for (int i = 0; i < n; i++) {
            sum[0][i] = 1;
        }
        
        for (int i = 0; i < m; i++) {
            sum[i][0] = 1;
        }
        
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                sum[i][j] = sum[i - 1][j] + sum[i][j - 1];
            }
        }
        return sum[m - 1][n - 1];
    }
View Code

4 Unique Paths II

    public int uniquePathsWithObstacles(int[][] obstacleGrid) 
    {
        if (obstacleGrid == null || obstacleGrid.length == 0 || obstacleGrid[0].length == 0) {
            return 0;
        }
        int m = obstacleGrid.length;
        int n = obstacleGrid[0].length;
        
        int[][] sum = new int[m][n];
        for (int i = 0; i < n; i++) {
            if (obstacleGrid[0][i] == 1) {
                break;
            }
            sum[0][i] = 1;
        }
        
        for (int i = 0; i < m; i++) {
            if (obstacleGrid[i][0] == 1) {
                break;
            }
            sum[i][0] = 1;
        }
        
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                if (obstacleGrid[i][j] == 1) {
                    continue;
                }
                sum[i][j] = sum[i - 1][j] + sum[i][j - 1];
            }
        }
        return sum[m - 1][n - 1];
    }
View Code

Sequence DP

1 Climbing Stairs

    public int climbStairs(int n) {
        // write your code here
        int f1 = 1;
        int f2 = 2;
        if (n == 1) {
            return f1;
        }
        if (n == 2) {
            return f2;
        }
        for (int i = 3; i <= n; i++) {
            int f3 = f1 + f2;
            f1 = f2;
            f2 = f3;
        }
        return f2;
    }
View Code

2 Jump Game

    public boolean canJump(int[] a) 
    {
        // wirte your code here
        if (a == null || a.length == 0)
        {
            return false;
        }
        int n = a.length;
        boolean[] can = new boolean[n];
        can[0] = true;
        for (int i = 1; i < n; i++) {
            for (int j = 0; j < i; j++) {
                if (can[j] && j + a[j] >= i) {
                    can[i] = true;
                    break;
                }
            }
        }
        return can[n - 1];
    }
View Code即使超时,也要掌握
    public boolean canJump(int[] a) 
    {
        // wirte your code here
        if (a == null || a.length == 0)
        {
            return false;
        }
        int fastest = a[0];
        for (int i = 1; i < a.length; i++) {
            if (fastest >= i && fastest < a[i] + i) {
                fastest = a[i] + i;
            }
        }
        return fastest >= a.length - 1;
    }
}
View Code

3 Jump Game II

    public int jump(int[] a)
    {
        // write your code here
        if (a == null || a.length == 0)
        {
            return 0;
        }
        int n = a.length;
        int[] step = new int[n];
        step[0] = 0;
        for (int i = 1; i < n; i++) {
            step[i] = Integer.MAX_VALUE;
            for (int j = 0; j < i; j++) {
                if (step[j] != Integer.MAX_VALUE && j + a[j] >= i) {
                    step[i] = Math.min(step[i], step[j] + 1);
                }
            }
        }
        return step[n - 1];
    }
View Code即使超时,也要掌握
    public int jump(int[] a)
    {
        // write your code here
        if (a == null || a.length == 0)
        {
            return 0;
        }
        int n = a.length;
        int start = 0; 
        int end = 0;
        int jump = 0;
        while (end < n - 1) {
            jump++;
            int fastest = end;
            for (int i = start; i <= end; i++) {
                fastest = Math.max(fastest, i + a[i]);
            }
            start = end + 1;
            end = fastest;
        }
        return jump;
    }
View Code

4 Decode Ways

    public int numDecodings(String s) {
        // Write your code here
        if (s == null || s.length() == 0 || s.charAt(0) == '0') {
            return 0;
        }
        int n = s.length();
        int[] num = new int[n + 1];
        num[0] = 1;
        num[1] = s.charAt(0) == '0' ? 0 : 1;
        for (int i = 2; i <= n; i++) {
            if (s.charAt(i - 1) != '0') {
                num[i] = num[i - 1];
            } 
            int twoDigit = (s.charAt(i - 2) - '0') * 10 + (s.charAt(i - 1) - '0');
            if (twoDigit >= 10 && twoDigit <= 26) {
                num[i] += num[i - 2];
            }
        }
        return num[n];
    }
View Code

5 Palindrome Partitioning II

    public int minCut(String s) 
    {
        // write your code here
        if (s == null || s.length() == 0)
        {
            return 0;
        }
        boolean[][] dict = getDict(s);
        int[] res = new int[s.length() + 1];
        res[0] = 0;
        for (int i = 0; i < s.length(); i++)
        {
            res[i + 1] = i + 1;
            for (int j = 0; j <= i; j++) {
                if (dict[j][i]) {
                    res[i + 1] = Math.min(res[i + 1], res[j] + 1);
                }
            }
        }
        return res[s.length()] - 1;
    }
    public boolean[][] getDict(String s)
    {
        boolean[][] dict = new boolean[s.length()][s.length()];
        for (int i = s.length() - 1; i >= 0; i--) {
            for (int j = i; j <= s.length() - 1; j++) {
                if (s.charAt(i) == s.charAt(j) && (j - i <= 2 || dict[i + 1][j - 1])) {
                    dict[i][j] = true;
                }
            }
        }
        return dict;
    }
View Code

6 Word Break

public boolean wordBreak(String s, Set<String> dict) {  
    if(s==null || s.length()==0)  
        return true;  
    boolean[] res = new boolean[s.length()+1];  
    res[0] = true;
    for(int i=1;i<=s.length();i++)  
    {  
        for (int j = 0; j < i; j++) {
            if (res[j] && dict.continues(s.substring(j, i)){
                res[j] = true;
                break;
            }
        }
    }  
    return res[s.length()];  
} 
}
View Code

7 Longest Increasing Continuous Subsequence

    public int longestIncreasingSubsequence(int[] nums) {
        // write your code here
        if (nums == null || nums.length == 0) return 0;
        int[] dp = new int[nums.length];
        int max = 0;
        for (int i = 0; i < nums.length; i++){
            dp[i] = 1;
            for (int j = 0; j < i; j++){
                if (nums[j] < nums[i]){
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                }
                max = Math.max(max, dp[i]);
            }
        }
        return max;
    }
View Code

two Sequence DP

1 Longest Common Subsequence

        public int longestCommonSubsequence(String a, String b) {
        // write your code here
        if (a == null || b == null || a.length() == 0 || b.length() == 0)
        {
            return 0;
        }
        int m = a.length();
        int n = b.length();
        int[][] dp = new int[m + 1][n + 1];
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (a.charAt(i - 1) == b.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } else {
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
                }
            }
        }
        return dp[m][n];
    }
View Code

2 Edit Distance

    public static int minDistance(String word1, String word2) 
    {  
        int m = word1.length();
        int n = word2.length();
        
        int[][] dp = new int[m + 1][n + 1];
        
        for (int i = 0; i <= n; i++) {
            dp[0][i] = i;
        }
        
        for (int i = 0; i <= m; i++) {
            dp[i][0] = i;
        }
        
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (word1.charAt(i - 1) == word2.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1];
                } else {
                    dp[i][j] = Math.min(dp[i - 1][j - 1], Math.min(dp[i - 1][j], dp[i][j - 1])) + 1; 
                }
            }
        }
        
        return dp[m][n];
    } 
View Code

3 Distinct Subsequences

    public int numDistinct(String s, String t)
    {
        int m = s.length();
        int n = t.length();
        int[][] dp = new int[m + 1][n + 1];
        for (int i = 0; i <= m; i++) {
            dp[i][0] = 1;
        }
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                dp[i][j] = dp[i - 1][j];
                if (s.charAt(i - 1) == t.charAt(j - 1)) {
                    dp[i][j] += dp[i - 1][j - 1];
                }
            }
        }
        return dp[m][n];
    }
View Code

4 Interleaving String

    public boolean isInterleave(String s1, String s2, String s3)
    {
        // write your code here
        if (s1.length() + s2.length() != s3.length())
        {
            return false;
        }
        int m = s1.length();
        int n = s2.length();
        boolean[][] dp = new boolean[m + 1][n + 1];
        dp[0][0] = true;
        for (int i = 1; i <= n; i++) {
            if (dp[0][i - 1] && s2.charAt(i - 1) == s3.charAt(i - 1)) {
                dp[0][i] = true;
            }
        }
        
        for (int i = 1; i <= m; i++) {
            if (dp[i - 1][0] && s1.charAt(i - 1) == s3.charAt(i - 1)) {
                dp[i][0] = true;
            }
        }
        
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (dp[i - 1][j] && s1.charAt(i - 1) == s3.charAt(i + j - 1) ||
                    dp[i][j - 1] && s2.charAt(j - 1) == s3.charAt(i + j - 1)) {
                        dp[i][j] = true;
                    }
            }
        }
        return dp[m][n];
    }
View Code
原文地址:https://www.cnblogs.com/whesuanfa/p/7444886.html