LeetCode6 dp

120. Triangle

我的解法用了一个二维数组,这样比较浪费空间。O(n*n)

但是标准答案自底向上,一是不需要进行特别判断,二是可以覆盖数组,则只需要O(n)的空间大小。

 

class Solution {
    public int minimumTotal(List<List<Integer>> triangle) {
        int size = triangle.size();
        if(size == 1) return triangle.get(0).get(0);
        int[][] dp = new int[size][size];
        dp[0][0] = triangle.get(0).get(0);
        int min = Integer.MAX_VALUE;
        for(int i = 1; i < size; i++){
            for(int j = 0; j <= i; j++){
                dp[i][j] = triangle.get(i).get(j);
                if(j == 0){
                    dp[i][j] += dp[i - 1][j];
                }else if(j == i){
                    dp[i][j] += dp[i - 1][j - 1];
                }else dp[i][j] += Math.min(dp[i - 1][j - 1], dp[i - 1][j]);
                if(i == size - 1) min = Math.min(min, dp[i][j]);
            }
        }
        return min;
    }
}

 他山之石:

class Solution {
    public int minimumTotal(List<List<Integer>> triangle) {
        int size = triangle.size();
        int[] dp = new int[size + 1];
        for(int i = size - 1; i >= 0; i--){
            for(int j = 0; j < triangle.get(i).size(); j++){
                dp[j] = Math.min(dp[j], dp[j+1]) + triangle.get(i).get(j);
            }
        }
        return dp[0];
    }
}

64. Minimun Path Sum

和上一题思路基本一致,采用了上一题的思路,只用了一个1d array。

class Solution {
    public int minPathSum(int[][] grid) {
        if(grid.length == 0) return 0;
        int m = grid.length;
        int n = grid[0].length;
        int[] dp = new int[n];
        for(int i = 0; i < m; i ++){
            for(int j = 0; j < n; j++){
                if(i == 0 && j == 0){
                    dp[j] = grid[0][0];
                }else if(i == 0){
                    dp[j] = grid[i][j] + dp[j - 1];
                }else if(j == 0){
                    dp[j] = grid[i][j] + dp[j];
                }else dp[j] = Math.min(dp[j - 1], dp[j]) + grid[i][j];
            }
        }
        return dp[n-1];
    }
}

62 Unique Path

还是一样的思路, 可以稍微简化一下,有一些值例如 j = 0的情况可以不需要便利。

class Solution {
    public int uniquePaths(int m, int n) {
        if( m <= 0 || n <= 0) return 0;
        int[] ans = new int[n];
        ans[0] = 1;
        for(int i = 0; i < m; i++){
            for(int j = 1; j < n; j++){
                if(i == 0){
                    ans[j] = ans[j - 1];
                }else ans[j] = ans[j] + ans[j - 1];
            }
        }
        return ans[n - 1];
    }
}

91 Decode Ways

class Solution {
    public int numDecodings(String s) {
        int len = s.length();
        if(len == 0) return 0;
        int[] dp = new int[len + 1];
        dp[0] = 1;
        dp[1] = s.charAt(0) == '0' ? 0 : 1;
        for(int i = 2; i <= len; i++){
            int first = Integer.parseInt(s.substring(i - 1, i));
            int second = Integer.parseInt(s.substring(i - 2, i));
            if(first > 0){
                dp[i] += dp[i - 1];
            }
            if(second >= 10 && second <= 26){
                dp[i] += dp[i - 2];
            }
        }
        return dp[len];
    }
}

这道题不难,但是有很多cornercase 需要处:

两位数不能大于26 不能小于10 否则无法构成两位数

一位数必须大于0

所以最好的方法还是分别取出两位数和个位数看是否符合条件,如果符合条件就加上。

posted @ 2017-12-06 02:37  nina阿瑶  阅读(111)  评论(0编辑  收藏  举报