刷題 - 島嶼數量

問題描述:

給你一個由 '1'(陸地)和 '0'(水)組成的的二維網格,請你計算網格中島嶼的數量。島嶼總是被水包圍,並且每座島嶼只能由水平方向或豎直方向上相鄰的陸地連接形成。此外,你可以假設該網格的四條邊均被水包圍。

對於網格類遍歷問題,深度優先搜索dfs是一種典型的解決方案,類比於二叉樹的DFS,其程序框架如下:

void dfs(TreeNode* node){
    if(node == NULL)
        return;
    dfs(node->left);
    dfs(node->right);
}

程序的思想是:(1)先判斷一下當前結點是否爲空,即判斷當前探索位置的有效性,(2)如果通過有效性判斷,則遞歸遍歷當前結點的孩子結點,或稱連通結點,進行結點探索。

二叉樹可以看作是一種簡單的無環的圖結構,對於網格問題,其實是一種複雜的圖結構,其dfs遍歷的思想框架與二叉樹其實是一致的,dfs流程同樣是先判斷,在遞歸遍歷:

(1)判斷條件:當前位置是否越界(網格通常是有邊界限制的);判斷當前結點是否滿足題目限制(如陸地爲1)

(2)遞歸遍歷:通常遍歷當前位置的“ 上、下、左、右” 四個位置。

class Solution {
public:
    int numIslands(vector<vector<char>>& grid) {
        int nr = grid.size();
        if (!nr) return 0;
        int nc = grid[0].size();
        int num_islands = 0;
        for (int r = 0; r < nr; ++r) {
            for (int c = 0; c < nc; ++c) {
                if (grid[r][c] == '1') {
                    ++num_islands;
                    dfs(grid, r, c);
                }
            }
        }
        return num_islands;
    }
private:
    void dfs(vector<vector<char>>& grid, int r, int c) {
        if (!inArea(grid, r, c))
            return;
        if(grid[r][c]!='1')
            return;
        grid[r][c] = '0';
        dfs(grid, r - 1, c);
        dfs(grid, r + 1, c);
        dfs(grid, r, c - 1);
        dfs(grid, r, c + 1);
    }
    bool inArea(vector<vector<char>>& grid, int r, int c) {
        return 0 <= r && r < grid.size() && 0 <= c && c < grid[0].size();
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章