跳動位元組19校招第二次線上筆試--第一題
阿新 • • 發佈:2018-12-31
題目:
大概題意如下:
出去玩, 需要分組, 每個人寫好自己認識的人的名單,如果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)
最後
如有錯誤請指正