你到底有多少个朋友圈?
2016-11-28 20:30
411 查看
有这样一道面试题它是这样描述的:假设有n个人m对好友(存于二维数组r),如果两个人是直接或间接的好友(好友的好友的好友...),则认为他们属于同一个朋友圈,请写程序求出这n个人里一共有多少个朋友圈?
例:n=5,m=3,r={{1,2},{2,3},{4,5}},表示有5个人,1和2是好友,2和3是好友,4和5是好友,则1,2,3属于同一个朋友圈,4,5属于同一个朋友圈.结果为两个朋友圈.
如何去分析这道面试题呢?这就用到并查集这种数据结构.
并查集>
将N个不同的元素分成一组不相交的集合,开始时,每个元素就是一个集合,然后按规律将两个集合进行合并,在合并的过程中要不断的查找这个元素属于哪个集合.
![](https://img-blog.csdn.net/20161128202517544?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
在统计朋友圈的数量的时候只需要统计负数的个数即可.
#pragma once
class UnionSet
{
public:
UnionSet(int size)
:_size(size+1)
{
_a=new int[size+1];
memset(_a,-1,sizeof(int)*(size+1));
}
~UnionSet()
{
delete[]_a;
_size=0;
}
void Merge(int x1,int x2)
{
int root1=_GetRoot(x1);
int root2=_GetRoot(x2);
if(root1 != root2)
{
_a[root1] += _a[root2];
_a[root2] = root1;
}
}
int CountFriends()
{
int count=0;
for(int i=0;i<_size;++i)
{
if(_a[i] < 0)
{
count++;
}
}
return count-1;
}
protected:
int _GetRoot(int index)
{
int root=index;
while(_a[root] >= 0)
{
root=_a[root];
}
return root;
}
protected:
int *_a;
int _size;
};
void testUnionSet()
{
const int n=5;
const int m=4;
int a[m][2]={{1,2},{2,3},{4,5},{1,3}};
UnionSet unionset(n);
for(int i=0;i<m;++i)
{
unionset.Merge(a[i][0],a[i][1]);
}
cout<<"Friends:"<<unionset.CountFriends()<<endl;
}
在这里就分享结束啦~~~
例:n=5,m=3,r={{1,2},{2,3},{4,5}},表示有5个人,1和2是好友,2和3是好友,4和5是好友,则1,2,3属于同一个朋友圈,4,5属于同一个朋友圈.结果为两个朋友圈.
如何去分析这道面试题呢?这就用到并查集这种数据结构.
并查集>
将N个不同的元素分成一组不相交的集合,开始时,每个元素就是一个集合,然后按规律将两个集合进行合并,在合并的过程中要不断的查找这个元素属于哪个集合.
在统计朋友圈的数量的时候只需要统计负数的个数即可.
#pragma once
class UnionSet
{
public:
UnionSet(int size)
:_size(size+1)
{
_a=new int[size+1];
memset(_a,-1,sizeof(int)*(size+1));
}
~UnionSet()
{
delete[]_a;
_size=0;
}
void Merge(int x1,int x2)
{
int root1=_GetRoot(x1);
int root2=_GetRoot(x2);
if(root1 != root2)
{
_a[root1] += _a[root2];
_a[root2] = root1;
}
}
int CountFriends()
{
int count=0;
for(int i=0;i<_size;++i)
{
if(_a[i] < 0)
{
count++;
}
}
return count-1;
}
protected:
int _GetRoot(int index)
{
int root=index;
while(_a[root] >= 0)
{
root=_a[root];
}
return root;
}
protected:
int *_a;
int _size;
};
void testUnionSet()
{
const int n=5;
const int m=4;
int a[m][2]={{1,2},{2,3},{4,5},{1,3}};
UnionSet unionset(n);
for(int i=0;i<m;++i)
{
unionset.Merge(a[i][0],a[i][1]);
}
cout<<"Friends:"<<unionset.CountFriends()<<endl;
}
在这里就分享结束啦~~~
相关文章推荐
- Oracle到底有多少数据库?
- 你每天的努力,到底值多少钱?
- 高性能网络编程(一):单台服务器并发TCP连接数到底可以有多少
- CSDN到底要多少积分才有排名(图解)
- String到底建了多少个对象
- 音频直播,这里面到底有多少坑
- js获取canvas 的宽和高,到底是多少?
- 人月到底有多少神话色彩
- SQLSERVER到底能识别多少个逻辑CPU?
- 梦想到底值多少钱?
- 概率论札记 - 2 - 用贝叶斯定理来讨论“医疗诊断的可靠性到底有多少”
- IBM站一个网页到底包含了多少技术--看分析
- int型的数到底最大值是多少?
- 想知你的博客到底值多少钱吗
- log不写底数时底数到底是多少?
- 假设银行一年整存零取的月息为0.63%。现在某人手中有一笔钱, 他打算在今后的5年中的每年年底取出1000元, 到底5年时刚好取完,请算出他存钱时应存入多少?
- 到底多少线程算是线程数太多?
- 【转】Windows 文件夹的秘密:Windows 目录到底占用了多少真实的硬盘空间
- 到底开发者需要掌握多少门语言?