动态规划Leetcode刷题记

[Leetcode][DP]动态规划相关题目汇总/分析/总结

2019-07-17  本文已影响0人  奔跑的程序媛A
  1. Unified Dimensional

  2. Two-dimensional

  3. Three-dimensional


[Unified Dimensional]

#70 Climbing Stairs
    public int climbStairs(int n) {
        if(n <= 2) return n;
        int i1 = 1, i2 = 2;
        for(int i = 3; i <= n; i++){
            int tmp = i1;
            i1 = i2;
            i2 = tmp + i1;
        }
        return i2;
    }
#91 Decode Ways
public int numDecodings(String s) {
        char[] ch = s.toCharArray();
        if(ch[0] == '0') return 0;
        if(ch.length < 2) return 1;
        int n = s.length();
        int i1 = 1, i2 = (ch[1] == 0 ? 0 : 1);
        int var = (ch[0]-'0') * 10 + (ch[1] - '0');
        if(var%10==0) i2 = 0;
        if(var >= 10 && var <= 26) i2++;
        for(int i = 2; i < n; i++){
            int tmp = (ch[i] == 0 ? 0 : i2);
            var = (ch[i-1]-'0') * 10 + (ch[i]-'0');
            if(var%10==0) tmp = 0;
            if(var >= 10 && var <= 26) tmp += i1;
            i1 = i2;
            i2 = tmp;
         }
        return i2;
    }
#120 Triangle
    public int minimumTotal(List<List<Integer>> triangle) {
        int row = triangle.size();
        int last_row_col = triangle.get(row-1).size();
        int[] dp = new int[last_row_col];
        for(int i = 0; i < last_row_col; i++){
            dp[i] = triangle.get(row-1).get(i);
        }
        for(int i = row-2; i >= 0; i--){
            for(int j = 0; j <= i; j++){
                dp[j] = triangle.get(i).get(j) + Math.min(dp[j], dp[j+1]);
            }
        }
        return dp[0];
        
    }
#139 Word Break
    public boolean wordBreak(String s, List<String> wordDict) {
        int n = s.length();
        boolean[] dp = new boolean[n+1];
        dp[0] = true;
        for(int i = 1; i <= n; i++){
            for(int j = 0; j < i; j++){
                String sub = s.substring(j, i);
                if(wordDict.contains(sub) && dp[j]){
                    dp[i] = true;
                    break;
                }
            }
        }
        return dp[n];
    }
#140 Word Break II
Map<Integer, List<String>> map; //index, res
    Set<String> dict;
    public List<String> wordBreak(String s, List<String> wordDict) {
        map = new HashMap<>();
        dict = new HashSet<>();
        for(String sh: wordDict) dict.add(sh);
        return help(s, s.length());
    }
    public List<String> help(String s, int end){
        List<String> res = new ArrayList<>();
        if(end == 0){
            res.add("");
            return res;
        }
        if(map.containsKey(end)) return map.get(end);
        for(int i = 0; i < end; i++){
            String sub = s.substring(i, end);
            if(dict.contains(sub)){
                List<String> next = help(s, i);
                for(String str: next){
                    res.add((str.length()==0)?sub : str + " " + sub);
                }
            }
        }
        map.put(end, res);
        return res;
    }
#198 House Robber
public int rob(int[] nums) {
        if(nums.length == 0) return 0;
        if(nums.length == 1) return nums[0];
        if(nums.length == 2) return Math.max(nums[0], nums[1]);
        int i1 = nums[0], i2 = Math.max(nums[0], nums[1]);
        int n = nums.length;
        for(int i = 2; i < n; i++){
            int tmp = Math.max(i1 + nums[i], i2);
            i1 = i2; 
            i2 = tmp;
        }
        return i2;
    }
#213 House Robber II
public int rob(int[] nums) {
        if(nums.length == 0) return 0;
        if(nums.length == 1) return nums[0];
        if(nums.length == 2) return Math.max(nums[0], nums[1]);
        int a = help(nums, 0, nums.length-1);
        int b = help(nums, 1, nums.length-1);
        return Math.max(a, b);
    }
    public int help(int[] nums, int s, int len) {
        if(len == 2) return Math.max(nums[s], nums[s+1]);
        int i1 = nums[s], i2 = Math.max(nums[s], nums[s+1]);
        for(int i = s+2; i < s+len; i++){
            int tmp = Math.max(i1 + nums[i], i2);
            i1 = i2; 
            i2 = tmp;
        }
        return i2;
    }
#279 Perfect Squares
    public int numSquares(int n) {
        int[] dp = new int[n+1];
        Arrays.fill(dp, Integer.MAX_VALUE);
        dp[0] = 0;
        for(int i = 1; i <= n; i++){
            for(int j = 1; j*j <= i; j++){
                dp[i] = Math.min(dp[i], 1 + dp[i-j*j]);
            }
        }
        return dp[n];
    }
#263 Ugly Number

easy

public boolean isUgly(int num) {
        if(num <= 0) return false;
        if(num == 1)  return true;
        while(num % 2 == 0) num /= 2;
        while(num % 3 == 0) num /= 3;
        while(num % 5 == 0) num /= 5;
        return num == 1;
    }
#264 Ugly Number II
public int nthUglyNumber(int n) {
        int p2 = 1, p3 = 1, p5 = 1;
        int[] dp = new int[n+1];
        dp[1] = 1;
        for(int i = 2; i <= n; i++){
            dp[i] = Math.min(Math.min(2 * dp[p2], 3 * dp[p3]), 5 * dp[p5]);
            if(dp[i] == 2 * dp[p2]) p2++;
            if(dp[i] == 3 * dp[p3]) p3++;
            if(dp[i] == 5 * dp[p5]) p5++;
        }
        return dp[n];
    }

[Two-dimensional]

#516 Longest Palindromic Subsequence

i 从后往前,j从i往后

public int longestPalindromeSubseq(String s) {
        int n = s.length();
        int[][] dp = new int[n][n];
        for(int i = 0; i < n; i++) dp[i][i] = 1;
        for(int i = n-1; i >= 0; i--){
            for(int j = i+1; j < n; j++){
                if(s.charAt(i) == s.charAt(j))
                    dp[i][j] = 2 + dp[i+1][j-1];
                else
                    dp[i][j] = Math.max(dp[i+1][j], dp[i][j-1]);
            }
        }
        return dp[0][n-1];
    }
#97 Interleaving String
public boolean isInterleave(String s1, String s2, String s3) {
        if (s3.length() != s1.length() + s2.length()) {
            return false;
        }
        int n1 = s1.length(), n2 = s2.length();
        boolean[][] dp = new boolean[n1+1][n2+1];
        //dp[0][0] = true;
        for(int i = 0; i <= n1; i++){
            for(int j = 0; j <= n2; j++){
                if(i == 0 && j == 0)
                    dp[0][0] = true;
                else if(i == 0)
                    dp[0][j] = dp[0][j-1] && s2.charAt(j-1) == s3.charAt(j-1);
                else if(j == 0)
                    dp[i][0] = dp[i-1][0] && s1.charAt(i-1) == s3.charAt(i-1);
                else
                    dp[i][j] = dp[i][j-1] && s2.charAt(j-1) == s3.charAt(i + j-1)
                    || dp[i-1][j] && s1.charAt(i-1) == s3.charAt(i + j-1);
            }
        }
        return dp[n1][n2];
    }
#62 Unique Paths
    public int uniquePaths(int m, int n) {
        int[][] dp = new int[n][m];
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                if(i == 0 || j == 0) dp[i][j] = 1;
                else dp[i][j] = dp[i-1][j] + dp[i][j-1];
            }
        }
        return dp[n-1][m-1];
    }
#63 Unique Paths II
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        int n = obstacleGrid.length;
        int m = obstacleGrid[0].length;
        int[][] dp = new int[n][m];
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                if(i==0 && j == 0) dp[i][j] = obstacleGrid[i][j] == 1 ? 0 : 1;
                else if(i == 0) dp[i][j] = obstacleGrid[i][j] == 1 ? 0 : dp[i][j-1];
                else if(j == 0) dp[i][j] = obstacleGrid[i][j] == 1 ? 0 : dp[i-1][j];
                else dp[i][j] = obstacleGrid[i][j] == 1 ? 0 : dp[i-1][j] + dp[i][j-1];
            }
        }
        return dp[n-1][m-1];
    }
#64 Minimum Path Sum
public int minPathSum(int[][] grid) {
        int n = grid.length;
        int m = grid[0].length;
        int[][] dp = new int[n][m];
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                if(i==0 && j==0) dp[i][j] = grid[i][j];
                else if(i == 0) dp[i][j] = dp[0][j-1] + grid[0][j];
                else if(j == 0) dp[i][j] = dp[i-1][0] + grid[i][0];
                else dp[i][j] = Math.min(dp[i-1][j], dp[i][j-1]) + grid[i][j];
            }
        }
        return dp[n-1][m-1];
    }
#72 Edit Distance
public int minDistance(String word1, String word2) {
        int n = word1.length();
        int m = word2.length();
        int[][] dp = new int[n+1][m+1];
        for(int i = 0; i <= n; i++){
            for(int j = 0; j <= m; j++){
                if(i == 0) dp[i][j] = j;
                else if(j == 0) dp[i][j] = i;
                else if(word1.charAt(i-1) == word2.charAt(j-1))
                    dp[i][j] = dp[i-1][j-1];
                else
                    dp[i][j] = 1 + Math.min(Math.min(dp[i-1][j-1], dp[i][j-1]), dp[i-1][j]);
            }
        }
        return dp[n][m];
    }
#10 Regular Expression Matching
public boolean isMatch(String s, String p) {
        int n = s.length();
        int m = p.length();
        boolean[][] dp = new boolean[n+1][m+1];
        dp[n][m] = true;
        for(int i = n; i >= 0; i--){
            for(int j = m-1; j >= 0; j--){
                boolean pre = i < n && (s.charAt(i) == p.charAt(j) || p.charAt(j) == '.');
                if(j+1 < m && p.charAt(j+1) == '*')
                    dp[i][j] = dp[i][j+2] || pre && dp[i+1][j];
                else
                    dp[i][j] = pre && dp[i+1][j+1];
            }
        }
        return dp[0][0];
    }
#221 Maximal Square
public int maximalSquare(char[][] matrix) {
        int n = matrix.length;
        int m = n == 0 ? 0 : matrix[0].length;
        int[][] dp = new int[n][m];
        int max_area = 0;
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                if(i == 0 || j == 0) dp[i][j] = matrix[i][j] - 48;
                else if(matrix[i][j] == '1'){
                    dp[i][j] = Math.min(Math.min(dp[i-1][j], dp[i][j-1]), dp[i-1][j-1]) + 1;
                }
                max_area = Math.max(dp[i][j] * dp[i][j], max_area);
            }
        }
        return max_area;
    }
#322 Coin Change
public int coinChange(int[] coins, int amount) {
        int[] dp = new int[amount+1];
        Arrays.fill(dp, amount+1);
        dp[0] = 0;
        for(int i = 1; i <= amount; i++){
            for(int coin : coins){
                if(coin <= i){
                    dp[i] = Math.min(dp[i-coin] + 1, dp[i]);
                } 
            }
        }
        return dp[amount] > amount ? -1 : dp[amount];
    }
#787 Cheapest Flights Within K Stops
    public int findCheapestPrice(int n, int[][] flights, int src, int dst, int K) {
        double[][] dp = new double[K+2][n];
        for(double[] row:dp) Arrays.fill(row, 1e9);
        dp[0][src] = 0;
        for(int i = 1; i <= K+1; i++){
            dp[i][src] = 0;
            for(int j = 0; j < flights.length; j++){
                dp[i][flights[j][1]] = Math.min(dp[i][flights[j][1]], dp[i-1][flights[j][0]] + flights[j][2]);
            }
            
        }
        return dp[K+1][dst] >= 1e9? -1 : (int)dp[K+1][dst];
    }

double因为Integer会有错误

#1035 Uncrossed Lines
public int maxUncrossedLines(int[] A, int[] B) {
        int n = A.length, m = B.length;
        int[][] dp = new int[n+1][m+1];
        for(int i = 0; i <= n; i++){
            for(int j = 0; j <= m; j++){
                if(i == 0 || j == 0) dp[i][j] = 0;
                else{
                    if(A[i-1] == B[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[n][m];
    }

[Three-dimensional]

#87 Scramble String
public boolean isScramble(String s1, String s2) {
        int len = s1.length();
        boolean[][][] dp = new boolean[len][len][len+1];
        for(int i = 0; i < len; i++){
            for(int j = 0; j < len; j++){
                dp[i][j][1] = s1.charAt(i) == s2.charAt(j);
            }
        }

        for(int k = 2; k <= len; k++){
            for(int i = 0; i <= len-k; i++){
                for(int j = 0; j <= len-k; j++){
                    for(int m = 1; m < k; m++)
                        if(dp[i][j][m] && dp[i+m][j+m][k-m]
||  dp[i][j+k-m][m] && dp[i+m][j][k-m]){
                            dp[i][j][k] = true;
                            break;
                        }
                        
                    
                }
            }
        }
        return dp[0][0][len];
    }

DFS会更快

#980 Unique Paths III
#741 Cherry Pickup
    int[][][] dp;
    public int cherryPickup(int[][] grid) {
        int n = grid.length;
        dp = new int[n][n][n];
        for (int[][] layer: dp)
            for (int[] row: layer)
                Arrays.fill(row, Integer.MIN_VALUE);
        return Math.max(0, help(grid, 0, 0, 0));
    }
    public int help(int[][] grid, int r1, int c1, int c2){
        int r2 = r1 + c1 - c2;
        int n = grid.length;
        if(r1 == n || r2 == n || c1 == n || c2 == n) return -999999;
        if(grid[r1][c1] == -1 || grid[r2][c2] == -1) return -999999;
        if(r1 == n-1 && c1 == n-1) return grid[r1][c1]; // base case
        if(dp[r1][c1][c2] != Integer.MIN_VALUE) return dp[r1][c1][c2];
        int res = grid[r1][c1] == 1 ? 1 :0;
        if(c1 != c2) res += grid[r2][c2] == 1 ? 1 :0;
        res += Math.max(
            Math.max(help(grid,r1, c1+1, c2+1), help(grid,r1+1, c1, c2+1)), 
            Math.max(help(grid,r1, c1+1, c2), help(grid,r1+1, c1, c2))
        );
        
        dp[r1][c1][c2] = res;
        return res;
    }
上一篇下一篇

猜你喜欢

热点阅读