力扣-200-岛屿的数量

传送门

题目分析:

对于只含有0和1的二维网路,题目实际上问的是二维网络中连通着的'1'的块数(这里的连通只能是上下左右连通)。那么,我们可以遍历二维网络,对于陆地(由'1'构成),搜索与其向连的'1'(陆地),$NumIsland$加一,当搜索完一块儿陆地(连着的'1')后,一定将他们变为'0',避免重复。

基于上述思想,做法有很多,比如搜索时用$bfs$和$dfs$均可,只不过$dfs$用递归实现,而$bfs$用队列实现。除此之外,也可以考虑用并查集实现相关连通块儿的合并,最后统计根节点的数目就行了。

方法一、深度优先搜索$dfs$

class Solution {public:
    int numIslands(vector<vector<char>>& grid) {        
        int num_island = 0;
        for(int i = 0; i < grid.size(); i++) {
            for(int j = 0; j < grid[0].size(); j++) {
                if(grid[i][j] == '1') {
                    num_island++;
                    dfs(grid, i, j);
                }
            }
        }
        return num_island;
    }
    
    void dfs(vector<vector<char>>& grid, int x, int y) {
        int dx[4] = {-1,0,1,0}, dy[4] = {0,1,0,-1};
        grid[x][y] = '0';   //避免重复遍历
        //深度优先搜索(迭代)
        for(int i = 0; i < 4; i++) {
            int xx = x + dx[i], yy = y + dy[i];
            if(xx >= 0 && xx < grid.size() && yy >= 0 && yy < grid[0].size() && grid[xx][yy] == '1')
                dfs(grid, xx, yy);
        }
    }
};

 

方法二、广度优先搜索$bfs$

#include <queue>
using namespace std;
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};
class Solution {
public:
    int numIslands(vector<vector<char>>& grid) {    
        int row = grid.size();
        if(!row) return 0;
        int col = grid[0].size();
        
        int num_island = 0;
        for(int i = 0; i < grid.size(); i++) {
            for(int j = 0; j < grid[0].size(); j++) {
                if(grid[i][j] == '1') {
                    num_island++;
                    grid[i][j] = '0'; //避免重复查找
                    queue<pair<int, int>> neighbors;
                    neighbors.push({i, j});
                    while(!neighbors.empty()) {
                        auto temp = neighbors.front();
                        neighbors.pop();
                        int x = temp.first, y = temp.second;
                        for(int k = 0; k < 4; k++) {
                            int xx = x + dx[k], yy = y + dy[k];
                            if(xx>=0 && xx<grid.size() && yy>=0 && yy<grid[0].size()) {
                                if (grid[xx][yy]=='1') {
                                    neighbors.push({xx, yy});
                                    grid[xx][yy] = '0';                                    
                                }
                            }
                        }
                    }
                }
            }
        }
        return num_island;
    }
};

 

方法三、并查集

#include <queue>
using namespace std;
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};
int par[100005];
int rak[100005];

class Solution {     
public:
    void init(int n) {  //  初始化
        for(int i = 0; i < n; i++) {
            par[i] = i;
            rak[i] = 0;
        }
    }
    
    int find(int x) {   //  寻找父亲节点
        if(par[x] == x) return x;
        else return par[x]=find(par[x]);
    }
    
    void unite(int x, int y) {
        x = find(x);
        y = find(y);
        if(x == y) return ; //x,y已经在一颗树上
        if(rak[x] < rak[y]) par[x] = y;
        else {
            par[y] = x;
            if (rak[x] == rak[y]) rak[x] ++;
        }
    }
    
    int numIslands(vector<vector<char>>& grid) {    
        int row = grid.size();
        if(!row) return 0;
        int col = grid[0].size();
        
        int count = row * col;       
        int num_island = 0;
        init(count);
        
        for(int i = 0; i < row; i++)
            for(int j = 0; j < col; j++) {
                if(grid[i][j] == '1') {
                    grid[i][j] = '-1';  //最后还要统计根节点的数目
                    for(int k = 0; k < 4; k++) {
                        int x = i + dx[k], y = j + dy[k];
                        if(x<0 || x>= row || y<0 || y>=col) continue;
                        if(grid[x][y]=='1') {
                            unite(i * col + j, x * col + y);
                        }
                    }
                }
            }
        for(int i = 0; i < row; i++) {
            for(int j = 0; j < col; j++) {
                if(par[i*col+j] == (i*col+j) && grid[i][j] !='0') num_island++;
            }
        }
        return num_island;
    }
};

 

posted @ 2020-08-11 18:44  Peterxiazhen  阅读(226)  评论(0编辑  收藏  举报