一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情。
给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
示例 1:
输入:grid = [ ["1","1","1","1","0"],
["1","1","0","1","0"],
["1","1","0","0","0"],
["0","0","0","0","0"]
]
输出:1
示例 2:
输入:grid = [ ["1","1","0","0","0"],
["1","1","0","0","0"],
["0","0","1","0","0"],
["0","0","0","1","1"]
]
输出:3
思路
这道题我们可以用二维表的dfs,遍历到一个就让他的上下左右都变成0,再次遍历的时候,就不再记录这个岛屿的数量了。
AC Code
DFS 做法
func numIslands(grid [][]byte) int {
var res int
for i:=0; i<len(grid); i++ {
for j:=0; j<len(grid[0]); j++ {
if grid[i][j] == '1' {
(1) res++
(2) dfsArea(grid,i,j)
}
}
}
return res
}
func dfsArea(grid [][]byte,r,c int){
h, w := len(grid), len(grid[0])
(3) if r < 0 || r >= h || c < 0 || c >= w {
return
}
(4) if grid[r][c]=='0'{
return
}
(5) grid[r][c]='0'
dfsArea(grid,r-1,c)
dfsArea(grid,r+1,c)
dfsArea(grid,r,c-1)
dfsArea(grid,r,c+1)
}
- (1) 当碰到1的时候就可以直接进行一次记录
- (2) 然后从这个1的位置开始dfs,知道遍历完上下左右都是0位置
- (3) 这里的边界条件是我们上下左右进行运算的时候要合理,不能超过这里的上下左右的边界
- (4) 如果这个r和c等于0也可以直接返回了。
- (5) 将遍历到的岛屿的1全部变成0,再继续进行一次遍历。
并查集做法
我们知道这个并查集是建立起来的即可!只要是碰到了导入就放入到查并集中,然后再查询这个查并集即可
func numIslands(grid [][]byte) int {
m := len(grid)
n := len(grid[0])
ans := 0
(1) dx := []int{-1, 0, 0, 1}
dy := []int{0, -1, 1, 0}
(2) fa := make([]int, m*n+1)
(3) for i := 0; i <= m*n; i++ {
fa[i] = i
}
(4) for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
(5) if grid[i][j] == '0' {
continue
}
for k := 0; k < 4; k++ {
nx := i + dx[k]
ny := j + dy[k]
(6) if nx >= m || ny >= n || nx < 0 || ny < 0 {
continue
(7) } else if grid[nx][ny] == '1' {
unionSet(fa, nums(n, i, j), nums(n, nx, ny))
}
}
}
}
(8) for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
(9) if grid[i][j] == '1' && Find(fa, nums(n, i, j)) == nums(n, i, j) {
ans++
}
}
}
return ans
}
- (1) 方向数组
- (2) 初始化并查集
- (3) 二维索引转一维
- (4) 循环网格
- (5) 如果碰到水则continue
- (6) 到了边界continue
- (7) 如果相邻是1,则加入并查集 uninonset
- (8) 最后查找并查集根的个数即可
- (9) 如果字符为1,且根是自己本身,说明找到一个根,ans++