栈解决岛屿数量问题与并集解决岛屿数量问题
这道题完全套用上篇的方式解决的,可能我下一次又不回了.主要是我思考不到将遍历到1的位置变为0,之后再重复进行这一点,很难.
给你一个由 '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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-of-islands
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
package com.atguigu.mycode;
import java.util.*;
/**
* @author nanhai
* @create 2021-02-02 14:42
*/
public class Solution {
// 深度优先,虽然我不懂为什么是深度,因为我感觉这个东西广度和深度差不多
// public static int numIslands(char[][] grid) {
// int count = 0;
// for(int i=0; i<grid.length; i++){
// for(int j=0; j<grid[i].length; j++){
// if(grid[i][j] == '1'){
// mark_one_to_zero(grid, i, j);
// count ++;
// }
// }
// }
// return count;
// }
//
// public static void mark_one_to_zero(char[][] grid, int i, int j){
// if(i <0 || i >=grid.length || j < 0 || j >=grid[i].length || grid[i][j] == '0') return;
// grid[i][j] = '0';
// mark_one_to_zero(grid, i+1, j);
// mark_one_to_zero(grid, i-1, j);
// mark_one_to_zero(grid, i, j+1);
// mark_one_to_zero(grid, i, j-1);
// }
private static Queue<int[]> queue = new LinkedList<int[]>();
public static int numIslands(char[][] grid) {
int count = 0;
int[] x_ = new int[]{1, -1, 0, 0};
int[] y_ = new int[]{0, 0, 1, -1};
for(int i=0; i<grid.length; i++){
for(int j=0; j<grid[i].length; j++){
if(grid[i][j] == '1'){
queue.add(new int[]{i, j});
count ++;
}
while(!queue.isEmpty()){
int[] cur = queue.poll();
int x = cur[0];
int y = cur[1];
for(int k=0; k<4; k++){
int x0 = x + x_[k];
int y0 = y + y_[k];
if(x0 >=0 && x0 < grid.length && y0 >= 0 && y0 <grid[i].length && grid[x0][y0] == '1'){
grid[x0][y0] = '0';
queue.add(new int[]{x0, y0});
}
}
}
}
}
return count;
}
public static void main(String[] args){
char[][] grid = new char[4][3];
grid[0] = new char[]{'1', '1', '1'};
grid[1] = new char[]{'0', '1', '0'};
grid[2] = new char[]{'1', '0', '0'};
grid[3] = new char[]{'1', '0', '1'};
System.out.println(numIslands(grid));
}
}
并集查找:
class UnionFind(object):
def __init__(self, grid):
self.row = len(grid)
self.col = len(grid[0])
self.parent = [-1 for i in range(self.row * self.col)]
self.count = 0
for i in range(self.row):
for j in range(self.col):
if grid[i][j] == "1":
self.parent[i * self.col + j] = i * self.col + j
self.count += 1
def find(self, v1):
if self.parent[v1] != v1:
self.parent[v1] = self.find(self.parent[v1])
return self.parent[v1]
@property
def get_count(self):
return self.count
def union(self, x, y):
p1 = self.find(x)
p2 = self.find(y)
if p1 != p2:
self.parent[p1] = p2
self.count -= 1
class Solution(object):
def numIslands(self, grid):
"""
:type grid: List[List[str]]
:rtype: int
"""
row = len(grid)
if row == 0:
return 0
col = len(grid[0])
uf = UnionFind(grid)
x_ = [-1, 1, 0, 0]
y_ = [0, 0, -1, 1]
for i in range(row):
for j in range(col):
if grid[i][j] == "1":
grid[i][j] = "0"
for k in range(len(x_)):
x0 = i + x_[k]
y0 = j + y_[k]
if 0 <= x0 < row and 0 <= y0 < col and grid[x0][y0] == "1":
uf.union(x0 * col + y0, i * col + j)
return uf.get_count
if __name__ == '__main__':
grid = [
["1", "1", "1", "1", "0"],
["1", "1", "0", "1", "0"],
["1", "1", "0", "0", "0"],
["0", "0", "0", "0", "0"]
]
target = "0202"
s1 = Solution()
root = s1.numIslands(grid)
print(root)
并集方式的优化方案(效率从小到大一次递增)
class UnionFind(object):
def __init__(self, ):
self.parent = [i for i in range(1, 8)]
self.parent.append(7)
print(self.parent)
def find(self, v1):
"""路径压缩,每次指向前面的一个,O(n)"""
while v1 != self.parent[v1]:
self.parent[v1] = self.parent[self.parent[v1]]
return self.parent[v1]
def find1(self, v1):
"""路径分裂,每次将cur和cur的上一个的节点同时指向各自父节点的父节点也就是爷爷节点"""
while v1 != self.parent[v1]:
cur_p = self.parent[v1]
pre_p = self.parent[self.parent[v1]]
self.parent[v1] = pre_p
self.parent[cur_p] = self.parent[self.parent[v1]]
v1 = self.parent[v1]
return v1
def find2(self, v1):
"""路径减半,将cur指向爷爷节点,cur的上一个指向也指向cur的爷爷节点"""
while v1 != self.parent[v1]:
self.parent[v1] = self.parent[self.parent[v1]]
v1 = self.parent[v1]
return v1
if __name__ == '__main__':
grid = [
["1", "1", "1", "1", "0"],
["1", "1", "0", "1", "0"],
["1", "1", "0", "0", "0"],
["0", "0", "0", "0", "0"]
]
target = "0202"
s1 = UnionFind()
root = s1.find(0)
print(root)