?62.不同路徑?
思路
機器人從(0 , 0) 位置出發,到(m - 1, n - 1)終點。
按照動規五部曲來分析:
1.確定dp數組(dp table)以及下標的含義
dp[i][j] :表示從(0 ,0)出發,到(i, j) 有dp[i][j]條不同的路徑。(并不是步數)
2.確定遞推公式
想要求dp[i][j],只能有兩個方向來推導出來,即dp[i - 1][j] 和 dp[i][j - 1]。
3.dp數組的初始化
首先dp[i][0]一定都是1,因為從(0, 0)的位置到(i, 0)的路徑只有一條(只能向下向右走),那么dp[0][j]也同理
4.確定遍歷順序
遞推公式dp[i][j] = dp[i - 1][j] + dp[i][j - 1],dp[i][j]都是從其上方和左方推導而來,那么從左到右一層一層遍歷就可以了。
5.舉例推導dp數組
代碼
class Solution {public int uniquePaths(int m, int n) {int[][] dp = new int[m][n];for (int i = 0; i < m; i++) {dp[i][0] = 1;}for (int i = 0; i < n; i++) {dp[0][i] = 1;}for (int i = 1; i < m; i++) {for (int j = 1; j < n; j++) {dp[i][j] = dp[i - 1][j] + dp[i][j - 1];}}return dp[m-1][n-1];}}
63. 不同路徑 II
思路
注意點:同樣只能想右或者向下,遇到障礙物就沒有辦法走,在初始化的時候障礙物之后的位置無法初始化即為0。
int[][] obstacleGrid obstacleGrid.length為行數 obstacleGrid[0].length為列數(第一行的元素的數量即為列數)
動規五部曲:
1.確定dp數組(dp table)以及下標的含義
dp[i][j] :表示從(0 ,0)出發,到(i, j) 有dp[i][j]條不同的路徑。
2.確定遞推公式
遞推公式和62.不同路徑一樣,dp[i][j] = dp[i - 1][j] + dp[i][j - 1]。有了障礙,(i, j)如果就是障礙的話應該就保持初始狀態(初始狀態為0)
3.dp數組如何初始化
因為從(0, 0)的位置到(i, 0)的路徑只有一條,所以dp[i][0]一定為1,dp[0][j]也同理。
但如果(i, 0) 這條邊有了障礙之后,障礙之后(包括障礙)都是走不到的位置了,所以障礙之后的dp[i][0]應該還是初始值0。
4.確定遍歷順序
從遞歸公式dp[i][j] = dp[i - 1][j] + dp[i][j - 1] 中可以看出,一定是從左到右一層一層遍歷,這樣保證推導dp[i][j]的時候,dp[i - 1][j] 和 dp[i][j - 1]一定是有數值。
5.舉例推導dp數組
代碼
class Solution {public int uniquePathsWithObstacles(int[][] obstacleGrid) {int m = obstacleGrid.length;int n = obstacleGrid[0].length; //行數列數可能會為1,故而不能使用obstacleGrid[1].lengthif (obstacleGrid[0][0] == 1 || obstacleGrid[m - 1][n - 1] == 1) {return 0;}int[][] dp = new int[m][n];for (int i = 0; i < m && obstacleGrid[i][0] == 0; i++) {dp[i][0] = 1;}for (int i = 0; i < n && obstacleGrid[0][i] == 0; i++) {dp[0][i] = 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];}}