小米面试题------朋友圈问题

题目描述:假如已知有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属于另一个朋友圈。结果为2个朋友圈。


解题思路:这个题要应用并查集来做,并查集:是一种树形结构,他是将N个不同的元素分成一组不想交的集合。刚开始,每个元素就是一个集合,按照规律将将两个集合进行合并。

刚开始时:有5个人,1~5,开辟一个大小为6的数组,然后都初始化为-1.



然后对集合进行合并。

对于集合{1,2},找每个元素的根节点,1和2的根节点是它自己,然后使1作为根节点,2最为子节点,然后下标为1的值减1,然后下标为2的值变为存它的根节点下标。


然后对于集合{2,3},找每个元素的根节点,2的根节点为1,3的根节点是它自己,可以发现集合{1,2}和集合{2,3}有一个共同元素,然后将它合并,将根节点1的值再减1,将下标为3的值变为存根节点1。


等等,最后图为:


代码为:

#pragma once
class UnionFindSet
{
public:
	UnionFindSet(int n)
		:_n(n)
	{
		_a=new int[n+1];
		for(size_t i=0;i<=n;++i)
		{
			_a[i]=-1;
		}
	}
	int FindRoot(int x)   //找根节点
	{
		while(_a[x]>=0)  //不是根
		{
			x=_a[x];
		}
		return x;
	}
	void Union(int x1,int x2)  //合并
	{
		int root1=FindRoot(x1);
		int root2=FindRoot(x2);
	    if(root1!=root2)
		{
			_a[root1]+=_a[root2];
		    _a[root2]=root1;
		}
	}
	int Count()   //统计几个朋友圈
	{
		int count=0;
		for(size_t i=0;i<=_n;++i)
		{
			if(_a[i]<=-1)
				count++;
		}
		return count-1;
	}
protected:
	int* _a;
	int _n;
};
int friends(int n,int m,int a[][2])
{
	UnionFindSet u(5);
	for(size_t i=0;i<m;++i)
	{
		u.Union (a[i][0],a[i][1]);
	}
	return u.Count ();
}
void TestUnionFindSet()
{
	int r[][2]={{1,2},{2,3},{4,5}};
	cout<<friends(5,3,r)<<endl;       //2
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值