算法之不按期更新(三)(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

相關文章
相關標籤/搜索