1. 程式人生 > >跳動位元組19校招第二次線上筆試--第一題

跳動位元組19校招第二次線上筆試--第一題

題目:

大概題意如下:

出去玩, 需要分組, 每個人寫好自己認識的人的名單,如果A的名單裡有B, B的名單裡有A, 表示兩個人相互認識; A的名單裡有B,B的名單裡有C, A可以和C間接認識。 分組的規則是, 如果兩個人相互認識, 或者能間接認識, 就可以分為一組。
現給出人N個, 和他們的名單, 求出能最少分多少個組。

用例如下:

var n = 10;//一共10個人
var arr = [
       [],            //第一個人沒有認識的人
       [5,3],         //第二個人認識第5個人和第三個人
       [8,4],         //同理
[9], [9], [3], [], [7,9], [], [9,7] ]

結果:

結果:2。
能分出兩個組, 第一個一組, 其他人一組

我的結果

思路:

使用廣搜的方式搜尋, 如果是一個沒有被判斷過的人, 就以它為起點, 將自己認識的人, 和自己認識的人認識的人遍歷到一個分組裡。 如果自己認識的人存在別的分組, 就將自己和別的分組合並在一起。

程式碼:

/**
 * n 總共的人數
 * arr 每個人認識人的情況
 * 通過arr得到分組情況
 * 通過橫向遍歷的方式
 * 有向圖的連通分量問題
 */
var n = 10; var arr = [ [], [5,3], [8,4], [9], [9], [3], [], [7,9], [], [9,7] ] function part (n , arr) { var list = []//佇列 var isUsed = []//任務是否被判斷過的陣列 var part = [] //裝分組的陣列 for (var i = 0; i < arr.length; i++){ var temp = [] if
(isUsed.indexOf(i) == -1){ list.push(i) isUsed.push(i) temp.push(i+1) var isPush = true while (list.length){ var now = list.shift()//需要遍歷的 var isContent = [] arr[now].forEach(function (value) { if(isUsed.indexOf(value-1) == -1){ isUsed.push(value - 1) list.push(value -1) temp.push(value) }else {//當前值可以和其他值相連 part.forEach(function (value2, index) { if (value2.indexOf(value) != -1){ isContent.push(index) } }) } }) isContent = [... new Set(isContent)] if(isContent.length){ isPush = false part[isContent[0]] = part[isContent[0]].concat(temp) for(var k = isContent.length-1; k > 0; k-- ){ part[isContent[0]] = part[isContent[0]].concat(part[isContent[k]]); part.splice(isContent[k], 1) } } } if (isPush){ part.push(temp) } } } console.log(part) } part(n, arr)

最後

如有錯誤請指正