题目:
大概题意如下:
出去玩, 需要分组, 每个人写好自己认识的人的名单,如果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)
最后
如有错误请指正