200. Number of Islands

仅供自己学习

 

思路:
题目的意思寻找有多少块全是 ‘1’的区域,即搜索 ‘1’直到其周围全是0为一个 计数。考虑使用BFS,从一个1向四周扩散的寻找。

首先判断grid是否为空,即行数是否为0,是则返回0。否则获取grid行列数。用两个for循环遍历所有的方格,用一个队列存储为‘1’的方格,每次找到一个为‘1’的方格就将它设为0,从队列获取一个‘1’的方格,搜索其上下左右的方格是否为1,如果为1则加入队列并设为0,当队列为空的时候,则找到了一个全为1并被0所包围的区域。

代码:

 1 class Solution {
 2 public:
 3     int numIslands(vector<vector<char>>& grid) {
 4         int nr=grid.size();
 5         if(!nr) return 0;
 6         int nc=grid[0].size();
 7         int nums_land=0;
 8         for(int r=0;r<nr;++r){
 9             for(int c=0;c<nc;++c){
10                 if(grid[r][c]=='1'){
11                     ++nums_land;
12                     grid[r][c]='0';
13                     queue<pair<int,int>> place;
14                     place.push({r,c});
15                     while(!place.empty()){
16                         auto rc=place.front();
17                         place.pop();
18                         int row=rc.first;
19                         int col=rc.second;
20                         if(row-1>=0&&grid[row-1][col]=='1'){
21                             place.push({row-1,col});
22                             grid[row-1][col]='0';
23                         }
24                         if(row+1<nr&&grid[row+1][col]=='1'){
25                             place.push({row+1,col});
26                             grid[row+1][col]='0';
27                         }
28                         if(col-1>=0&&grid[row][col-1]=='1'){
29                             place.push({row,col-1});
30                             grid[row][col-1]='0';
31                         }
32                         if(col+1<nc&&grid[row][col+1]=='1'){
33                             place.push({row,col+1});
34                             grid[row][col+1]='0';
35                         }
36                     }
37                 }
38             }
39         }
40         return nums_land;
41     }
42 };

 

既然BFS能解决那么DFS同样也可以。思路大体是一样的,只是将BFS的地方循环调用DFS,DFS中再在每个方向递归调用DFS即可。

 

代码:

 1 class Solution {
 2 public:
 3     void DFS(vector<vector<char>>& grid,int r,int c){   
 4         int nr=grid.size();
 5         int nc=grid[0].size();
 6 
 7         grid[r][c] ='0';
 8         if(r-1>= 0 && grid[r-1][c]=='1') DFS(grid,r-1,c);
 9         if(r+1< nr && grid[r+1][c]=='1') DFS(grid,r+1,c);
10         if(c-1>= 0 && grid[r][c-1]=='1') DFS(grid,r,c-1);
11         if(c+1< nc && grid[r][c+1]=='1') DFS(grid,r,c+1);
12     }
13     int numIslands(vector<vector<char>>& grid) {
14         int nr = grid.size();
15         if(!nr) return 0;
16         int nc = grid[0].size();
17         int nums_land=0;
18         for(int r=0;r< nr;++r){
19             for(int c=0;c< nc;++c){
20                 if(grid[r][c]=='1'){
21                     ++nums_land;
22                     DFS(grid,r,c);
23                 }
24             }
25         }
26         return nums_land;
27     }
28 
29 };

 

BFS这种将 1变0的方法和查并集思想相同,那么同样也可以用查并集解决。

直接调用查并集的模板,两个for循环遍历所有方格,判断如果该方格四周是方格1的,那么就将其设为同一个leader,思想和BFS一样。

代码:

 1 class UnionFind {
 2 public:
 3     UnionFind(vector<vector<char>>& grid) {
 4         count = 0;
 5         int m = grid.size();
 6         int n = grid[0].size();
 7         for (int i = 0; i < m; ++i) {
 8             for (int j = 0; j < n; ++j) {
 9                 if (grid[i][j] == '1') {
10                     parent.push_back(i * n + j); //不为0的方格的leader设为其位置
11                     ++count;         //记录有1的方格数
12                 }
13                 else {
14                     parent.push_back(-1);//为0的方格leader设为-1
15                 }
16                 rank.push_back(0);
17             }
18         }
19     }
20 
21     int find(int i) {
22         if (parent[i] != i) {
23             parent[i] = find(parent[i]);
24         }
25         return parent[i];
26     }
27 
28     void unite(int x, int y) {
29         int rootx = find(x);
30         int rooty = find(y);
31         if (rootx != rooty) {
32             if (rank[rootx] < rank[rooty]) {
33                 swap(rootx, rooty);
34             }
35             parent[rooty] = rootx;
36             if (rank[rootx] == rank[rooty]) rank[rootx] += 1;
37             --count;  //每将一个方格leader改为相同的就减去1,最后剩下的就是count就是岛屿数
38         }
39     }
40 
41     int getCount() const {
42         return count;
43     }
44 
45 private:
46     vector<int> parent;
47     vector<int> rank;
48     int count;
49 };
50 
51 class Solution {
52 public:
53     int numIslands(vector<vector<char>>& grid) {
54         int nr = grid.size();
55         if (!nr) return 0;
56         int nc = grid[0].size();
57 
58         UnionFind uf(grid);
59         for (int r = 0; r < nr; ++r) {
60             for (int c = 0; c < nc; ++c) {
61                 if (grid[r][c] == '1') {
62                     grid[r][c] = '0';
63                     if (r - 1 >= 0 && grid[r-1][c] == '1') uf.unite(r * nc + c, (r-1) * nc + c);
64                     if (r + 1 < nr && grid[r+1][c] == '1') uf.unite(r * nc + c, (r+1) * nc + c);
65                     if (c - 1 >= 0 && grid[r][c-1] == '1') uf.unite(r * nc + c, r * nc + c - 1);
66                     if (c + 1 < nc && grid[r][c+1] == '1') uf.unite(r * nc + c, r * nc + c + 1);
67                 } //这部分和BFS将1改为0的部分意思相同,将其四周为1的方格的leader设为相同的 也就是记为同一块区域
68             }
69         }
70 
71         return uf.getCount();
72     }
73 };

 

posted @ 2021-02-19 18:35  Mrsdwang  阅读(61)  评论(0)    收藏  举报