返回

解码LeetCode 547: 省份数量——图的连通分量之旅

后端

如今的社交网络图谱中,人物、信息、事件被层层交织,构成了错综复杂的网络世界,寻找其间的连通分量成为剖析网络的重要手段。LeetCode 547: 省份数量向你发出了挑战,以一个矩阵呈现出人物之间的好友关系,你需要识别出图中独立的省份数目,即连通分量的数量。

算法之旅就此启程!

算法一:深度优先搜索——沿迹寻踪

深度优先搜索,如同勘探者沿着错综复杂的洞穴,不断深入探索,追寻洞穴的连通路径,最终揭示整个洞穴的布局。应用于图的连通分量问题时,我们从任意一个节点开始,不断访问其未访问过的相邻节点,直至无法继续延伸,再从另一个未访问过的节点重新开始,直至所有节点都被访问过。

def findCircleNum(isConnected):
    def dfs(i):
        visited.add(i)
        for j in range(n):
            if isConnected[i][j] == 1 and j not in visited:
                dfs(j)

    n = len(isConnected)
    visited = set()
    count = 0
    for i in range(n):
        if i not in visited:
            dfs(i)
            count += 1
    return count

算法二:并查集——聚沙成塔

并查集,又名不相交集合,是一个维护不相交集合的的数据结构。其核心操作在于集合的合并和查找,从而能够快速确定两个元素是否属于同一个集合。解决连通分量问题时,我们可将每个人初始化为一个独立的集合,当发现两人相连时,将两人的集合合并为一个集合。最后,统计集合的数量即可得到连通分量的数目。

def findCircleNum(isConnected):
    n = len(isConnected)
    parents = [i for i in range(n)]

    def find(x):
        if x != parents[x]:
            parents[x] = find(parents[x])
        return parents[x]

    def union(x, y):
        px, py = find(x), find(y)
        parents[px] = py

    for i in range(n):
        for j in range(i + 1, n):
            if isConnected[i][j] == 1:
                union(i, j)

    count = 0
    for i in range(n):
        if i == parents[i]:
            count += 1

    return count

算法选择:棋逢对手

深度优先搜索与并查集,两者各具特色。深度优先搜索简洁易懂,操作量更小,空间开销较少;并查集则在数据结构上更胜一筹,无论是查找还是合并集合,其复杂度都接近常数级,因此在大规模数据下表现更加出色。

结语:算法之美

连通分量的探索,既是算法思想的展现,也是逻辑思维的体现。LeetCode 547: 省份数量,正是算法之美在编程世界中的缩影。探索算法的奥秘,在于不断尝试、深入思考,让算法成为你解决问题的利器。