著名的克鲁斯卡尔算法应用了并查集,仔细探究了一番,此人写的较为详细。
http://blog.youkuaiyun.com/dm_vincent/article/details/7655764
http://blog.youkuaiyun.com/dm_vincent/article/details/7769159
另外,小米2013年的应届生笔试题,考了类似的一题,现在捏来看看:
假如已知有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个朋友圈。
最后请分析所写代码的时间、空间复杂度。评分会参考代码的正确性和效率。
C/C++:
int friends(int n , int m , int* r[]);
Java:
int friends(int n , int m , int[][] r);
我的实现:
public class UnionSet {
private static int id[]={0,0,0,0,0,0,0,0,0,0,0,0};
public static int find(int i)
{
while(i!=id[i])
{
id[i] = id[id[i]];
i = id[i];
}
return i;
}
public static void merge(int i,int j)
{
int root_i = find(i);
int root_j = find(j);
if(root_i<root_j)
id[root_j] = root_i;
else{
id[root_i] = root_j;
}
}
public static int getCountSet(int n,int m,int left[],int right[])
{
int count = 0;
for(int i=0;i<n;i++)
id[i] = i;
for(int i=0;i<m;i++)
merge(left[i],right[i]);
for(int i=0;i<n;i++)
{
if(id[i]==i)
count++;
}
return count;
}
public static void main(String []args)
{
//n = 5 , m = 3 , r = {{1 , 2} , {2 , 3} , {4 , 5}}
int n = 5, m = 3;
int left[] = {1,2,4};
int right[] = {2,3,5};
int count = getCountSet(n,m,left,right);
System.out.println(count);
}
}