日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

动态规划立体匹配代码_411,动态规划和递归求不同路径 II

發布時間:2025/3/20 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 动态规划立体匹配代码_411,动态规划和递归求不同路径 II 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

問題描述

一個機器人位于一個 m x n 網格的左上角 (起始點在下圖中標記為“Start” )。

機器人每次只能向下或者向右移動一步。機器人試圖達到網格的右下角(在下圖中標記為“Finish”)。

現在考慮網格中有障礙物。那么從左上角到右下角將會有多少條不同的路徑?

網格中的障礙物和空位置分別用 1 和 0 來表示。

說明:m 和 n 的值均不超過 100。

示例 1:

輸入:

[

[0,0,0],

[0,1,0],

[0,0,0]

]

輸出: 2

解釋:

3x3 網格的正中間有一個障礙物。

從左上角到右下角一共有 2 條不同的路徑:

1. 向右 -> 向右 -> 向下 -> 向下

2. 向下 -> 向下 -> 向右 -> 向右

動態規劃解決

前面我們講過的409,動態規劃求不同路徑和這非常類似的一道題,只不過上一篇沒有障礙物,但并不影響我們解這道題,我們還用dp[i][j]表示到坐標(i,j)這個格內有多少條不同的路徑,所以最終的答案就是求dp[m-1][n-1]。

這里的遞推分為兩種情況,一種是當前網格沒有障礙物,一種是當前網格有障礙物。

1,如果當前網格dp[i][j]有障礙物,那么這里肯定是走不過去的,所以dp[i][j]=0。

2,如果當前網格dp[i][j]沒有障礙物,那么遞推公式就和上一題409,動態規劃求不同路徑一樣了。

因為只能從上面或左邊走過來,所以遞推公式是

dp[i][j]=dp[i-1][j]+dp[i][j-1]。

  • dp[i-1][j]表示的是從上面走過來的路徑條數。
  • dp[i][j-1]表示的是從左邊走過來的路徑條數。

邊界條件也好判斷,如果當前行沒有障礙物,那么當前行的值都是1,如果有障礙物,那么第一個障礙物前面都是1,其他的都是0。同理第一列也一樣。

我們來看下代碼

public?int?uniquePathsWithObstacles(int[][]?obstacleGrid)?{????int?m?=?obstacleGrid.length;????int?n?=?obstacleGrid[0].length;????int?dp[][]?=?new?int[m][n];????//第一列初始化????for?(int?i?=?0;?i?

代碼和409,動態規劃求不同路徑差不多,只不過在第一行和第一列還有上面第21行多了一些判斷。

動態規劃代碼量優化

上面代碼雖然也能實現,但有那么多條件判斷總感覺很繁瑣,所以我們還有一種方式就是把二維數組的長和寬都放大一格,這樣數組的第一行和第一列都不存儲任何值,但初始條件要變了

  • dp[1][1] = obstacleGrid[0][0] ^ 1;
  • dp[0][1] = 1;
  • dp[1][0] = 1;

上面3種初始條件都可以,我們來任選一個,看下代碼

public?int?uniquePathsWithObstacles(int[][]?obstacleGrid)?{????int?m?=?obstacleGrid.length;????int?n?=?obstacleGrid[0].length;????int?dp[][]?=?new?int[m?+?1][n?+?1];????//初始條件,下面3個任選一個????//dp[1][1]?=?obstacleGrid[0][0]?^?1;????//dp[0][1]?=?1;????dp[1][0]?=?1;????for?(int?i?=?1;?i?<=?m;?++i)????????for?(int?j?=?1;?j?<=?n;?++j)????????????if?(obstacleGrid[i?-?1][j?-?1]?==?0)????????????????dp[i][j]?+=?dp[i?-?1][j]?+?dp[i][j?-?1];????return?dp[m][n];}

動態規劃空間優化

我們可以參照上一題把二維空間改為一維的,原理很簡單,我們來直接看代碼

public?int?uniquePathsWithObstacles(int[][]?obstacleGrid)?{????int?m?=?obstacleGrid.length;????int?n?=?obstacleGrid[0].length;????int[]?dp?=?new?int[n?+?1];????dp[1]?=?1;????for?(int?i?=?0;?i?

上一題有人問過一個問題說看不懂第11行,這里再說一下,因為是一行一行的遍歷,在當前行遍歷之前dp(這里是一維數組)表示的是上一行的值,然后遍歷到當前行的時候,假如遍歷當前行的第j列的時候,那么當前行第j列之前的數據都會被更新掉,當前行第j列之后的數據還是上一行的,所以dp[j]=dp[j]+dp[j-1](為了區分,這里標成了不同的顏色),dp[j]表示的是當前列的上一行值,dp[j-1]表示的是當前行的前一個值。

遞歸方式

上一題我們提到過,使用遞歸的方式會造成大量的重復計算,所以為了減少重復計算,這里使用一個map把計算過的值存儲起來,下次用的時候先從map中取,如果有就返回,如果沒有再計算。

public?int?uniquePathsWithObstacles(int[][]?obstacleGrid)?{????return?helper(obstacleGrid,?0,?0,?new?HashMap());}public?static?int?helper(int[][]?obstacleGrid,?int?down,?int?right,?Map?map)?{????String?key?=?down?+?"and"?+?right;????int?result?=?0;????if?(map.containsKey(key))????????return?map.get(key);????if?(obstacleGrid[down][right]?==?1)?{????????result?=?0;????????map.put(key,?result);????????return?result;????}????if?(right?==?obstacleGrid[0].length?-?1?&&?down?==?obstacleGrid.length?-?1)?{????????if?(obstacleGrid[down][right]?==?1)?{????????????result?=?0;????????}?else?{????????????result?=?1;???????}????????map.put(key,?result);????????return?result;????}????if?(right?==?obstacleGrid[0].length?-?1?||?down?==?obstacleGrid.length?-?1)?{????????if?(right?==?obstacleGrid[0].length?-?1)?{????????????result?=?helper(obstacleGrid,?down?+?1,?right,?map);????????}?else?{????????????result?=?helper(obstacleGrid,?down,?right?+?1,?map);????????}????????map.put(key,?result);????????return?result;????}????result?=?helper(obstacleGrid,?down,?right?+?1,?map)?+?helper(obstacleGrid,?down?+?1,?right,?map);????map.put(key,?result);????return?result;}

這種不看也可以,因為動態規劃非常簡單,沒人會傻到會使用這種方式,但他也算是提供了一種思路,有時間看看也行。

總結

這題多了一個障礙物的判斷,但難度其實并沒有增加多少,如果當前位置出現了障礙物,說明不能從當前位置通過,所以當前位置的路徑是0,如果當前位置不是0,那么計算就還和以前一樣了。

如果喜歡這篇文章還可以關注微信公眾號“數據結構和算法”,查看更多的算法題

總結

以上是生活随笔為你收集整理的动态规划立体匹配代码_411,动态规划和递归求不同路径 II的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。