你有一个用于表示一片土地的整数矩阵land,该矩阵中每个点的值代表对应地点的海拔高度。若值为0则表示水域。由垂直、水平或对角连接的水域为池塘。池塘的大小是指相连接的水域的个数。编写一个方法来计算矩阵中所有池塘的大小,返回值需要从小到大排序。
示例:
输入:
[
[0,2,1,0],
[0,1,0,1],
[1,1,0,1],
[0,1,0,1]
]
输出: [1,2,4]
class Solution {
public int[] pondSizes(int[][] land) {
UnionfindLinkNode u = new UnionfindLinkNode(land.length, land[0].length, land);
for (int i = 0; i < land.length; i++) {
for (int j = 0; j < land[i].length; j++) {
int cur = land[i][j];
if (cur == 0) {
//左边
if (j > 0 && land[i][j- 1] == 0) {
u.union(i, j, i, j - 1);
}
//上边
if (i > 0 && land[i - 1][j] == 0) {
u.union(i, j, i - 1, j);
}
//上斜边1
if (j > 0 && i > 0 && land[i -1][j- 1] == 0) {
u.union(i, j, i-1, j - 1);
}
//上斜边2
if (j < land[i].length -1 && i > 0 && land[i-1][j + 1] == 0) {
u.union(i, j, i-1, j + 1);
}
}
}
}
return u.find(0);
}
}
class UnionfindLinkNode {
private Node[][] nodes;
private int size;
private int num;
private int rowSize;
private int colSize;
public UnionfindLinkNode(int rowSize, int colSize,int[][] arr) {
nodes = new Node[rowSize][colSize];
for (int i = 0; i < rowSize; i++) {
for (int j = 0; j < colSize; j++) {
nodes[i][j] = new Node(arr[i][j], 1);
}
}
this.size = rowSize * colSize;
this.num = this.size;
this.rowSize = rowSize;
this.colSize = colSize;
}
public int[] find(int val) {
Set<Node> list = new HashSet<>();
for (int i = 0; i < rowSize; i++) {
for (int j = 0; j < colSize; j++) {
Node node = nodes[i][j];
if (node.first.x == val) {
list.add(node.first);
}
}
}
int[] arr = new int[list.size()];
int i = 0;
Iterator<Node> it = list.iterator();
while (it.hasNext()) {
arr[i++] = it.next().cnt;
}
Arrays.sort(arr);
return arr;
}
public boolean union(int x, int y, int x1, int y1) {
if (x1 < 0 || y1 < 0 || x1 >= rowSize || y1 >= colSize) {
return false;
}
Node nodeX = nodes[x][y];
Node nodeY = nodes[x1][y1];
//代表节点
Node firstX = nodeX.first;
Node firstY = nodeY.first;
if (firstX == firstY) {
return false;
}
firstX.setCnt(firstX.getCnt() + firstY.getCnt());
//尾节点
Node tailX = firstX.pre;
Node tailY = firstY.pre;
tailX.next = firstY;
firstY.pre = tailX;
tailY.next = firstX;
firstX.pre = tailY;
//更新y链表的代表节点
Node start = firstY;
while (start != tailY) {
start.first = firstX;
start = start.next;
}
tailY.first = firstX;
size--;
System.out.println(x + ":" + y + ":" + size);
return true;
}
public boolean isSameSet(int x, int y, int x1, int y1) {
return nodes[x][y].first == nodes[x1][y1].first;
}
public int size() {
return size;
}
}
class Node {
//上一个节点
Node pre = this;
//下一个节点
Node next = this;
//代表节点
Node first = this;
//值
int x;
//节点数
int cnt;
public Node(int x, int cnt) {
this.x = x;
this.cnt = cnt;
}
public int getCnt() {
return cnt;
}
public void setCnt(int cnt) {
this.cnt = cnt;
}
}
计算矩阵中池塘大小:算法与实现
本文介绍了一种算法,用于计算给定整数矩阵中由水域构成的池塘大小,通过Union-Find数据结构实现连通组件的查找,结果按从小到大排序。实例演示了如何应用此方法解决实际问题。
1749

被折叠的 条评论
为什么被折叠?



