200. Number of Islands
Description
Given a 2d grid map of '1'
s (land) and '0'
s (water), count the
number of islands. An island is surrounded by water and is formed
by connecting adjacent lands horizontally or vertically. You may
assume all four edges of the grid are all surrounded by water.
Example1
Input:
11110
11010
11000
00000
Output: 1
Example2
Input:
11000
11000
00100
00011
Output: 3
Solution
由于之前做过一个使用并查集的类似的题目.
链接: LeetCode-130 与 并查集
因此, 直接写代码.
Code1
class UF
{
private:
int *pa;
int *rank;
int count;
public:
UF(int N) {
count = N;
pa = new int[N];
rank = new int[N];
for(int i = 0; i < N; i++) {
pa[i] = i;
rank[i] = 0;
}
}
~UF() {
delete []pa;
delete []rank;
}
// 是否同一颗子树.
bool find(int a, int b) {
return getroot(a) == getroot(b);
}
// 返回当前子树根节点.
int getroot(int a) {
while (pa[a] != a) a = pa[a];
return a;
}
// 将任意两个结点所在的树合并.
void unichild(int a, int b) {
a = getroot(a);
b = getroot(b);
if(a != b) {
if(rank[a] > rank[b]) {
pa[b] = a;
} else if(rank[a] < rank[b]) {
pa[a] = b;
} else {
pa[b] = a;
rank[a]++;
}
count--;
}
}
int getcount() {return count;}
};
class Solution { // '1' 代表 land, '0' 代表 water
public: // 返回所有的 "islands" (个人思路, 想到了之前的并查集!)
int numIslands(vector<vector<char>>& grid) {
int n = grid.size();
if(!n) return 0;
int m = grid[0].size();
UF uf = UF(m*n+1); // 使用一个虚拟的 root, 来合并所有的'1'
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
if(grid[i][j] == '0') {
uf.unichild(i*m+j, n*m);
} else {
if(i != 0 && grid[i-1][j] == '1') uf.unichild((i-1)*m+j, i*m+j);
if(j != 0 && grid[i][j-1] == '1') uf.unichild(i*m+j-1, i*m+j);
}
}
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
cout<<uf.getroot(i*m + j)<<" ";
}
cout<<endl;
}
return uf.getcount()-1;
}
};
Code2
利用栈实现的 dfs
class Solution {
public:
/**
* 判断岛屿数量
* @param grid char字符型vector<vector<>>
* @return int整型
*/
int ret, n, m;
vector<int> move;
bool checkPoint(int i, int j) {
return (i >= 0 && j >= 0 && i < n && j < m);
}
void dealOne(vector<vector<char>> &grid, int i, int j) {
if (!checkPoint(i, j)) return ;
stack<pair<int, int>> stk;
stk.push(pair<int, int>(i, j));
pair<int, int> p;
int ii, jj;
while (!stk.empty()) {
p = stk.top();
stk.pop();
for (int x = 0; x < 4; x++) {
ii = p.first + move[x];
jj = p.second + move[x+1];
if (checkPoint(ii, jj) && grid[ii][jj] == '1') {
stk.push(pair<int, int>(ii, jj));
}
}
grid[p.first][p.second] = '0';
}
}
int solve(vector<vector<char> >& grid) {
// write code here
ret = 0;
n = grid.size();
if (!n) return 0;
m = grid[0].size();
move = {-1, 0, 1, 0, -1};
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (grid[i][j] == '1') {
dealOne(grid, i, j);
ret++;
}
}
}
return ret;
}
};