62. 不同路径

image.png

  1. public int uniquePaths(int m, int n) {
  2. int[][] dp = new int[m][n];
  3. for (int i = 0; i < m; i++) {
  4. dp[i][0] = 1;
  5. }
  6. for (int i = 0; i < n; i++) {
  7. dp[0][i] = 1;
  8. }
  9. for (int i = 1; i < m; i++) {
  10. for (int j = 1; j < n; j++) {
  11. dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
  12. }
  13. }
  14. return dp[m - 1][n - 1];
  15. }

63. 不同路径 II

image.png

  1. 确定dp数组(dp table)以及下标的含义

dp[i][j] :表示从(0 ,0)出发,到(i, j) 有dp[i][j]条不同的路径。

  1. 确定递推公式

递推公式和62.不同路径一样,dp[i][j] = dp[i - 1][j] + dp[i][j - 1]。 但这里需要注意一点,因为有了障碍,(i, j)如果就是障碍的话应该就保持初始状态(初始状态为0)。

  1. dp数组如何初始化

如果(i, 0) 这条边有了障碍之后,障碍之后(包括障碍)都是走不到的位置了,所以障碍之后的dp[i][0]应该还是初始值0。

  1. 确定遍历顺序

从递归公式dp[i][j] = dp[i - 1][j] + dp[i][j - 1] 中可以看出,一定是从左到右一层一层遍历,这样保证推导dp[i][j]的时候,dp[i - 1][j] 和 dp[i][j - 1]一定是有数值。

  1. public int uniquePathsWithObstacles(int[][] obstacleGrid) {
  2. if(obstacleGrid==null||obstacleGrid.length==0) return 0;
  3. if(obstacleGrid[0][0]==1) return 0;
  4. int m=obstacleGrid.length,n=obstacleGrid[0].length;
  5. int[][] dp=new int[m][n];
  6. dp[0][0]=1;
  7. for(int i=1;i<n;i++){
  8. if(dp[0][i-1]==1&&obstacleGrid[0][i]==0){
  9. dp[0][i]=1;
  10. }
  11. }
  12. for(int i=1;i<m;i++){
  13. if(dp[i-1][0]==1&&obstacleGrid[i][0]==0){
  14. dp[i][0]=1;
  15. }
  16. }
  17. for(int i=1;i<m;i++){
  18. for(int j=1;j<n;j++){
  19. if(obstacleGrid[i][j]==1){
  20. dp[i][j]=0;
  21. }else{
  22. dp[i][j]=dp[i-1][j]+dp[i][j-1];
  23. }
  24. }
  25. }
  26. return dp[m-1][n-1];
  27. }

343. 整数拆分

image.png

  1. 确定dp数组(dp table)以及下标的含义

dp[i]:表示第i个数可以获得的最大乘积。

  1. 确定递推公式

因为n可以拆分成至少两个正整数,令j 是第一个被拆分的数字,则剩下的部分为(i -j ), (i-j)可以选择继续拆分,或者不拆分

  1. dp数组如何初始化

如果(i, 0) 这条边有了障碍之后,障碍之后(包括障碍)都是走不到的位置了,所以障碍之后的dp[i][0]应该还是初始值0。

  1. 确定遍历顺序

从递归公式dp[i][j] = dp[i - 1][j] + dp[i][j - 1] 中可以看出,一定是从左到右一层一层遍历,这样保证推导dp[i][j]的时候,dp[i - 1][j] 和 dp[i][j - 1]一定是有数值。

  1. public int integerBreak(int n) {
  2. int[] dp = new int[n + 1];
  3. for (int i = 2; i <= n; i++) {
  4. int curMax = 1;
  5. for (int j = 1; j < i; j++) {
  6. curMax = Math.max(curMax, Math.max(j * (i - j), j * dp[i - j]));
  7. }
  8. dp[i] = curMax;
  9. }
  10. return dp[n];
  11. }