如何统计矩阵连通值数量?非暴力求解最大连通组及集群大小
嘿,我来帮你拆解这几个矩阵连通性的问题,用高效的方法避开暴力解法,一步步讲清楚:
1. 统计矩阵中连通值的数量
这里的“连通值的数量”,其实就是统计每个不同数值对应的连通块个数(或者所有数值的连通块总数,看你具体需求)。要避开逐个元素Flood Fill的暴力操作,咱们用**Union-Find(并查集)**来高效处理:
- 先初始化并查集:每个矩阵元素单独作为一个集合,同时用哈希表记录每个数值的初始连通块计数(初始时,每个数值的计数等于它在矩阵中出现的总次数)。
- 遍历矩阵的每个元素,只检查右侧和下方的相邻元素(避免重复处理同一对元素):
- 如果当前元素和相邻元素数值相同,且两者不在同一个集合里,就合并它们的集合,同时把该数值的连通块计数减1(两个块合并成一个,计数自然减1)。
- 遍历结束后,哈希表里的每个数值对应的计数就是该数值的连通块数量,把所有数值的计数加起来就是总的连通块数量。
2. 找出最大连通值组的大小(仅上下左右连通,非暴力Flood Fill)
Union-Find依然是最优解,比逐个Flood Fill更高效(尤其是大矩阵场景),具体步骤如下:
- 初始化并查集:
- 给每个矩阵元素分配唯一索引:比如m行n列的矩阵中,元素(i,j)的索引可以设为
i*n + j。 - 初始化
parent数组(记录每个元素的根节点)和size数组(记录每个集合的大小,初始值全为1)。
- 给每个矩阵元素分配唯一索引:比如m行n列的矩阵中,元素(i,j)的索引可以设为
- 遍历合并连通元素:
- 逐个遍历每个元素(i,j):
- 检查右侧元素(i,j+1):如果j+1 < n,且当前元素和右侧元素数值相同,就尝试合并两者的集合。
- 检查下方元素(i+1,j):如果i+1 < m,且当前元素和下方元素数值相同,就尝试合并两者的集合。
- 合并时,找到两个元素的根节点,若根节点不同,就把小集合合并到大集合里,同时更新大集合的
size值。
- 逐个遍历每个元素(i,j):
- 查找最大连通组大小:遍历整个
size数组,取出最大的数值,就是你要的答案。
举个你给的示例数组(整理成4x4矩阵):
8 3 3 3 1 2 3 8 1 2 5 6 6 2 3 9
用这个方法处理时:
- 第一行的三个3会依次合并成一个集合(size=3);
- 第二行第三列的3和第一行第三列的3数值相同,合并后集合size变成4;
- 其他连通块比如第一列的两个1会合并成size=2,第三列的三个2合并成size=3;
- 最终最大的连通组就是那个size=4的3的集群,和你说的示例结果完全一致。
变种问题:找出矩阵中最大集群的大小(自定义集群条件)
你提到的变种问题没写完具体的集群规则,但核心思路还是基于Union-Find做扩展:
- 只需要修改合并集合的判断条件:不再是“数值相同”才合并,而是替换成你自定义的集群规则(比如元素值相差不超过k、属于同一类别标签、满足某种数学关系等)。
- 后续的初始化、遍历合并、查找最大size的步骤和上面完全一致,只需要把合并判断逻辑换成你的自定义条件就行。
比如如果变种条件是“集群内元素值相差不超过1”,那处理时只要相邻元素的差值≤1,就可以尝试合并它们的集合,最后找最大的集合size即可。
内容的提问来源于stack exchange,提问作者Bob Billy
相关产品推荐
相关产品推荐

