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
所以最好的方法还是分别取出两位数和个位数看是否符合条件,如果符合条件就加上。