《演算法設計與分析》第八週作業
阿新 • • 發佈:2018-11-26
《演算法設計與分析》第八週作業
標籤(空格分隔): 課堂作業
文章目錄
姓名:李**
學號:16340114
題目:Unique Paths II(https://leetcode.com/problems/unique-paths-ii/description/)
題目概要
給定一個m*n的矩陣,矩陣中設有障礙物,有一個機器人在矩陣的左上角,機器人每一步只能往下或者往右移動,且不能通過障礙物,問機器人到達右下角的路徑有多少條。
思路
這個題目可以用動態規劃的思想去解決。把“到達右下角的路徑數目”轉換成“到達右下角左邊的格子的路徑數目”與“到達右下角上方的格子的路徑數目”之和。用這個思路推導下去,就能得到這樣的狀態遷移方程:
pathNum[i][j] = pathNum[i - 1][j] + pathNum[i][j - 1]
(當pathNum[i - 1][j]或pathNum[i][j - 1]不存在時,其值為0)
特別地,如果左上角沒有障礙物,那麼從左上角到左上角的路徑數為1。而有障礙物的格子的路徑數為0。
具體實現
利用狀態遷移方程編寫方程就可以解決問題了。需要注意的是,如果使用遞迴的方式實現,不但效率低下, 還會重複計算某些狀態。注意到,一個格子的路徑數是依賴於該格子上方和左方的格子的路徑數的,因此只需從上往下,從左到右計算矩陣中格子的路徑數就可以得到答案,而不會出現重複計算格子路徑數的情況。此外,額外處理左上角起點的格子和有障礙物的格子即可。
心得
這大概算是比較簡單的動態規劃問題了吧,感覺自己對動態規劃的理解還不是很到位。把下週的課上完再去挑戰更難的題目也許會輕鬆一點。
原始碼:
class Solution { public: int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) { int height = obstacleGrid.size(); int width = obstacleGrid[0].size(); int** pathNum = new int* [height]; for (int i = 0; i < height; ++i) { pathNum[i] = new int [width]; } pathNum[0][0] = !obstacleGrid[0][0]; for (int i = 0; i < height; ++i) { for (int j = 0; j < width; ++j) { if (i == 0 && j == 0) continue; if (obstacleGrid[i][j] == 1) pathNum[i][j] = 0; else pathNum[i][j] = ( i == 0 ? 0 : pathNum[i - 1][j] ) + ( j == 0 ? 0 : pathNum[i][j - 1]); } } int answer = pathNum[height - 1][width - 1]; for (int i = 0; i < height; ++i) { delete [] pathNum[i]; } delete [] pathNum; return answer; } };