1. 程式人生 > 實用技巧 >LeetCode200. 島嶼數量

LeetCode200. 島嶼數量

非常經典的搜尋問題。遍歷陣列,從每一個1開始深度優先搜尋當前位置聯通的位置是否都是1(也就是與它聯通的陸地),用一個額外的布林陣列visited記錄每一個位置的元素是否已經訪問過,每個遍歷過的位置visited都標記為true。

程式碼如下:

class Solution {
public:
    vector<vector<bool>> visited;
    int res = 0, rows, cols;
    int dx[4] = {1, 0, 0, -1}, dy[4] = {0, 1, -1, 0};            //這兩個陣列表示x,y的方向
    
    void DFS(int x, int y, vector<vector<bool>>& visited, vector<vector<char>>& grid) {
        visited[x][y] = true;
        for(int i = 0; i < 4; ++i) {                            //搜尋四個方向
            int newX = x + dx[i], newY = y + dy[i];            //計算下一個位置
            if(newX < 0 || newX >= rows || newY < 0 || newY >= cols || grid[newX][newY] != '1' || visited[newX][newY]) {      //如果新位置越界或者不為1或者已經訪問過了,就跳過
                continue;
            }
            DFS(newX, newY, visited, grid);                   //否則從下一個位置繼續尋找聯通的1
        }
    }

    int numIslands(vector<vector<char>>& grid) {     
        if(grid.size() == 0 || grid[0].size() == 0) {
            return 0;
        }
        rows = grid.size(), cols = grid[0].size();
        visited = vector<vector<bool>>(rows, vector<bool>(cols, false));
        for(int i = 0; i < rows; ++i) {
            for(int j = 0; j < cols; ++j) {
                if(grid[i][j] == '1' && !visited[i][j]) {      //找到了一個沒有被訪問過的陸地起點,更新答案數,從這個位置開始DFS,尋找所有與他聯通的1,並更新visited陣列
                    ++res;
                    DFS(i, j, visited, grid);
                }
            }
        }
        return res;
    }
};