前言
新的一年,好好学习。
正文
问题来源
本问题来自leetcode上的200题。
问题描述
给定一个由 ’1’(陆地)和 ‘0’(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。
示例 1:
输入:
11110
11010
11000
00000
输出: 1
示例 2:
输入:
11000
11000
00100
00011
输出: 3
分析:
深度优先
func numIslands(grid [][]byte) int {
count := 0
for i := 0; i < len(grid); i++ {
for j := 0; j < len(grid[i]); j++ {
if grid[i][j] != '0' {
count++
dfs(grid, i, j)
}
}
}
return count
}
func dfs(grid [][]byte, i, j int) {
if grid[i][j] == '0' {
return
}
grid[i][j] = '0'
row := len(grid)
col := len(grid[i])
if i > 0 {
dfs(grid, i-1, j)
}
if j > 0 {
dfs(grid, i, j-1)
}
if i < row - 1 {
dfs(grid, i+1, j)
}
if j < col - 1 {
dfs(grid, i, j+1)
}
}
/**
func dfs(grid [][]byte, i, j int) {
row := len(grid)
col := len(grid[0])
if i < 0 || i >= row || j < 0 || j >= col {
return
}
if grid[i][j] == '0' {
return
}
grid[i][j] = '0'
dfs(grid, i-1, j)
dfs(grid, i, j-1)
dfs(grid, i+1, j)
dfs(grid, i, j+1)
}
*/
广度优先
var dirs = []point{
{
x: 0,
y: 1,
},
{
x: 1,
y: 0,
},
{
x: -1,
y: 0,
},
{
x: 0,
y: -1,
},
}
type point struct {
x int
y int
}
// 广度搜索 numIslands
func numIslands(grid [][]byte) int {
if len(grid) == 0 {
return 0
}
m := len(grid)
n := len(grid[0])
queue := make([]point,0)
num := 0
for i := range grid {
for j, val := range grid[i] {
if val == 49 {
queue = append(queue, point{i,j})
num++
for len(queue) >0 {
temp := queue[0]
queue = queue[1:]
if grid[temp.x][temp.y] == 48 {
continue
}
grid[temp.x][temp.y] = 48
for _,dir := range dirs {
x := temp.x + dir.x
y := temp.y + dir.y
if x>=0 && x < m && y >=0 && y <n {
if grid[x][y] == 49 {
queue = append(queue,point{x,y})
}
}
}
}
}
}
}
return num
}
并查集解法
也可以考虑用并查集来做这题,将二维数组重新编号,从0开始,从左到右,从上到下,直到nm-1(其中n为行数,m为列数),对于位置(i,j)则编号为im+j,那么相邻(左右,上下)的为同一个值,则认为他们相通。那么最终只要统计一下father[i]==i且对应值为1的个数即可。
class Solution {
public:
int findFather(vector<int> &father,int a){
int f=a;
while(father[f]!=f){
f=father[f];
}
while(father[a]!=a){
int z=a;
a=father[z];
father[a]=f;
}
return f;
}
void unionFather(vector<int> &father, int a,int b){
int fa=findFather(father,a);
int fb=findFather(father,b);
if(fa!=fb){
father[fa]=fb;
}
}
int numIslands(vector<vector<char>>& grid) {
if(grid.size()==0||grid[0].size()==0) return 0;
int n=grid.size(),m=grid[0].size(),k=n*m;
vector<int> father(k,-1);
for(int i=0;i<k;i++){
father[i]=i;
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
int t1=i*m+j;
int t2=t1+1,t3=t1+m;
if(j+1<m&&grid[i][j]==grid[i][j+1]) unionFather(father,t1,t2);
if(i+1<n&&grid[i][j]==grid[i+1][j]) unionFather(father,t1,t3);
}
}
int res=0;
for(int i=0;i<k;i++){
if(father[i]==i&&grid[i/m][i%m]=='1'){
res+=1;
}
}
return res;
}
};
总结:
勤思考。
结语
不管怎么样好好加油。