1. 程式人生 > >《演算法設計與分析》第八週作業

《演算法設計與分析》第八週作業

《演算法設計與分析》第八週作業

標籤(空格分隔): 課堂作業

文章目錄

姓名:李**
學號: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;
    }
};