62.不同路徑
62. 不同路徑 - 力扣(LeetCode)
本題大家掌握動態規劃的方法就可以。 數論方法 有點非主流,很難想到。
代碼隨想錄
視頻講解:動態規劃中如何初始化很重要!| LeetCode:62.不同路徑_嗶哩嗶哩_bilibili
dp數組含義:從m*n格子左上角到右上角有幾種走法
遞推公式:dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
初始化:dp[i][1] = 1? dp[1][i] = 1?
遍歷順序:從左往右
class Solution {public int uniquePaths(int m, int n) {int[][] dp = new int[m + 1][n + 1];for(int i = 1;i < m + 1;i++){dp[i][1] = 1;}for(int i = 1;i < n + 1;i++){dp[1][i] = 1;}for(int i = 2;i < m + 1;i++){for(int j = 2;j < n + 1;j++){dp[i][j] = dp[i - 1][j] + dp[i][j - 1];}}return dp[m][n];}
}
63. 不同路徑 II
63. 不同路徑 II - 力扣(LeetCode)
https://programmercarl.com/0063.%E4%B8%8D%E5%90%8C%E8%B7%AF%E5%BE%84II.htmlhttps://programmercarl.com/0063.%E4%B8%8D%E5%90%8C%E8%B7%AF%E5%BE%84II.html
視頻講解:動態規劃,這次遇到障礙了| LeetCode:63. 不同路徑 II_嗶哩嗶哩_bilibili
dp數組含義:從當前位置到目標位置有幾種走法
遞歸公式:dp[i][j] = dp[i + 1][j] + dp[i][j + 1];
初始化:n - 1列?m - 1行,從左向右從上到下找到最后一個出現的障礙,障礙和之前的dp都是0
其他位置如果有障礙,dp也是0
遍歷順序:從右向左,從下到上
class Solution {public int uniquePathsWithObstacles(int[][] obstacleGrid) {int m = obstacleGrid.length;int n = obstacleGrid[0].length;int[][] dp = new int[m][n];int mem = -1;//初始化n - 1列for(int i = 0;i < m;i++){if(obstacleGrid[i][n - 1] == 1){mem = i;dp[i][n - 1] = 0;}else{dp[i][n - 1] = 1;}}if(mem != -1){for(int i = 0;i < mem;i++){dp[i][n - 1] = 0;}}mem = -1;//初始化m - 1行for(int i = 0;i < n;i++){if(obstacleGrid[m - 1][i] == 1){mem = i;dp[m - 1][i] = 0;}else{dp[m - 1][i] = 1;}}if(mem != -1){for(int i = 0;i < mem;i++){dp[m - 1][i] = 0;}}for(int i = m - 2;i >= 0;i--){for(int j = n - 2;j >= 0;j--){//碰到障礙就是0種走法if(obstacleGrid[i][j] == 1)dp[i][j] = 0;//從右向左遍歷else dp[i][j] = dp[i + 1][j] + dp[i][j + 1];}}return dp[0][0];}
}
隨想錄的,dp的含義是從00到該目標位置有幾種走法,從左向右遍歷
初始化第一行第一列,沒有障礙物賦1,只要遇到一個障礙物就賦0,后面都是0
class Solution {public int uniquePathsWithObstacles(int[][] obstacleGrid) {int m = obstacleGrid.length;int n = obstacleGrid[0].length;int[][] dp = new int[m][n];//如果在起點或終點出現了障礙,直接返回0if (obstacleGrid[m - 1][n - 1] == 1 || obstacleGrid[0][0] == 1) {return 0;}for (int i = 0; i < m && obstacleGrid[i][0] == 0; i++) {dp[i][0] = 1;}for (int j = 0; j < n && obstacleGrid[0][j] == 0; j++) {dp[0][j] = 1;}for (int i = 1; i < m; i++) {for (int j = 1; j < n; j++) {dp[i][j] = (obstacleGrid[i][j] == 0) ? dp[i - 1][j] + dp[i][j - 1] : 0;}}return dp[m - 1][n - 1];}
}
-
整數拆分?
343. 整數拆分 - 力扣(LeetCode)
代碼隨想錄
視頻講解:動態規劃,本題關鍵在于理解遞推公式!| LeetCode:343. 整數拆分_嗶哩嗶哩_bilibili
class Solution {public int integerBreak(int n) {if(n == 2)return 1;int[] dp = new int[n + 1];dp[2] = 1;dp[3] = 2;int temp = 0;for(int i = 3;i < n + 1;i++){for(int j = 1;j <= i/2;j++){dp[i] = Math.max(j * dp[i - j],j*(i - j));dp[i] = Math.max(dp[i],temp);temp = dp[i];}}return dp[n];}
}
-
不同的二叉搜索樹 (跳過)
本題思路并不容易想,一刷建議可以跳過。 如果學有余力,可以看視頻理解一波。
代碼隨想錄
視頻講解:動態規劃找到子狀態之間的關系很重要!| LeetCode:96.不同的二叉搜索樹_嗶哩嗶哩_bilibili