算法之不按期更新(三)(2018-04-24)

题目

input:算法

  • n // 表明无向图的顶点数 // 从1开始
  • m // 无向图的边数
  • arr1 // 各边的状况,形如[[1, 2], [3, 4],...](表明顶点0和顶点2相连,顶点3和顶点4相连)
  • arr2 // 但愿求得的连通状况数组,形如[[1, 3], [1, 4], ...] (表明但愿知道顶点1,顶点3的连通状况,顶点1和顶点4的连通状况)

output: numarr2中能够连通的数量数组

示例: input:code

  • n = 3
  • m = 1
  • arr1 = [[1, 3]]
  • arr2 = [[2, 3]]

output: 0leetcode

下面是我解决这个题的时候的思路input





















解题思路

这个题,刚拿到的时候,我最初的想法是使用无向图的邻接矩阵,而后在检查点的时候经过广度优先遍历查看两个点是否连通。实现这个想法以后就发现,时间复杂度真的过高了。每一次都会产生许多的无用查询。hash

而后我想了另一个思路,既然只查询两个点是否连通,那么咱们维护一个连通集合不就能够了。一开始每个孤立的点都是一个单独的连通集合,形如['1', '2', '3', '4'],在加上一条边以后,就是该边的两个顶点所在的连通集合合并成同一个连通集合,即加上边[1, 3]后,连通集合变成['13', '2', '4']。这样,在查询的时候,去寻找顶点B是否在顶点A所处的连通集合里就能够了。因而我写出了以下的代码。io

代码

function solution(n, m, arr1, arr2) {
    let hash = new Array(n + 1) // 表明每一个点的所在的连通集合,undefined表明这个点还不与其余点相连,0位无效
    let map = {} // 保留每一个联通集合的点集
    let index = 1 // 下一个联通集合的编号
    for (let i = 0; i < m; i++) { // 依次添加边到连通集合里
        let edge = arr1[i]
        let A = edge[0] // 顶点A
        let B = edge[1] // 顶点B
        if (hash[A] === undefined && hash[B] === undefined) { // 这两个都是孤立的点,新建一个连通集合
            hash[A] = index
            hash[B] = index
            map[index++] = [A, B]
        } else if (hash[B] === undefined) { // 点A不是孤立的,点B是孤立的,把B加入A的连通集合里
            hash[B] = hash[A]
            map[hash[A]].push(B)
        } else if (hash[A] === undefined) { // 点B不是孤立的,点A是孤立的,把A加入B的连通集合里
            hash[A] = hash[B]
            map[hash[B]].push(A)
        } else if (hash[A] !== hash[B]) { // A,B均不是孤立的,把B的连通集合,加入A的连通集合里
            B_list = map[hash[B]] // B所在的连通集合的顶点列表
            group = hash[A]
            for (let i = B_list.length - 1; i >= 0; i--) { // 每一个顶点的连通集合修改成A的
                hash[B_list[i]] = group
            }
            map[group] = map[group].concat(map[hash[B]])
            delete map[hash[B]]
        }
    }
    let result = 0 // 连通的数量
    for (let i = arr2.length - 1; i >= 0; i--) {
        let test = arr2[i]
        let groupA = hash[test[0]]
        let groupB = hash[test[1]]
        if (groupA && groupB && groupA === groupB) {
            result++
        }
    }
    return result
}

也就是,用hash来存放对应的点所在的连通集合,map存放连通集合对应的点。function


本期算法小分享就到这里咯(leetcode刚作完探索里的初级,还有好多已经说烂了的题就不分享了。)若是有什么意见或者想法欢迎在评论区和我交流test

相关文章
相关标签/搜索