方法一:深度优先遍历
注意事项:无须状态重置。
C++ 代码:
#include <iostream>
#include <vector>
using namespace std;
class Solution {
private:
int dx[4] = {0, 0, -1, 1};
int dy[4] = {-1, 1, 0, 0};
int rows;
int cols;
bool inArea(int x, int y) {
return x >= 0 && x < rows && y >= 0 && y < cols;
}
void dfs(int x, int y, vector<vector<char>> &grid) {
if (grid[x][y] == '0') {
return;
}
grid[x][y] = '0';
for (int i = 0; i < 4; ++i) {
int newX = x + dx[i];
int newY = y + dy[i];
if (inArea(newX, newY) && grid[newX][newY] == '1') {
dfs(newX, newY, grid);
}
}
}
public:
int numIslands(vector<vector<char>> &grid) {
rows = grid.size();
if (rows == 0) {
return 0;
}
cols = grid[0].size();
if (cols == 0) {
return 0;
}
int res = 0;
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
if (grid[i][j] == '1') {
dfs(i, j, grid);
res++;
}
}
}
return res;
}
};
方法二:并查集
public class Solution {
private class UnionFind {
private int[] parent;
/**
* 连通分量个数
*/
private int count;
public UnionFind(int n) {
count = n;
parent = new int[n];
for (int i = 0; i < n; i++) {
parent[i] = i;
}
}
public int find(int x) {
while (x != parent[x]) {
parent[x] = parent[parent[x]];
x = parent[x];
}
return x;
}
public void union(int x, int y) {
int rootX = find(x);
int rootY = find(y);
if (rootX == rootY) {
return;
}
parent[rootX] = rootY;
count--;
}
}
private boolean inArea(int x, int y, int rows, int cols) {
return x >= 0 && x < rows && y >= 0 && y < cols;
}
private int getIndex(int x, int y, int cols) {
return x * cols + y;
}
public int numIslands(char[][] grid) {
int rows = grid.length;
if (rows == 0) {
return 0;
}
int cols = grid[0].length;
if (cols == 0) {
return 0;
}
int[][] directions = new int[][]{{0, 1}, {1, 0}};
int size = rows * cols;
// 多开一个结点,把 '0' 都与最后这个结点连在一起
UnionFind unionFind = new UnionFind(size + 1);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (grid[i][j] == '1') {
for (int[] direction : directions) {
int newX = i + direction[0];
int newY = j + direction[1];
if (inArea(newX, newY, rows, cols) && grid[newX][newY] == '1') {
unionFind.union(getIndex(i, j, cols), getIndex(newX, newY, cols));
}
}
} else {
unionFind.union(getIndex(i, j, cols), size);
}
}
}
return unionFind.count - 1;
}
}