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 };

浙公网安备 33010602011771号