阿里题目:明星群众问题
阿里的题目:有n-1个群众和1个明星,群众两两间可能认识也可能不认识,但是群众都认识明星,明星不认识其他任何人。现在每次询问一个人是否认识另一个人的时间复杂度是O(1),要求找出明星的时间复杂度。
笔试时,完全不知道在写什么。题目似乎都没有分析清楚。胡搞了一番,老是对着“群众都认识明星”这个point思考。结论就是O(n^2),晕。
其实,切入点应该为“只有一个明星,群众都认识明星,明星不认识群众”(说等没说),引用网络得出的一个重要的结论:首先分析一次询问的效果。is A 认识 B? (yes) A不是明星,B可能是明星 : (no) A可能是明星,B是群众。所以一次询问可以确定一个人。所以一次询问可以确定一个人。
每一次可以确定一个人,所以要确定明星, 时间复杂度为O(n)。
数据结构的设计:
如果i认识j,记作i大于等于j ,同样,j不一定大于等于i,满足要求,i不认识j记作i<j,对明星k,他不认识所有人,则k是其中最小的数,且满足其余的人都认识他,也就是其余的人都大于等于k.这样问题就被转换了:找未知序列数中的唯一最小数。
1 int func38(int a[], int n) 2 { 3 assert (a && n>1); 4 int i; 5 int stari = 0; //存放最小数在a中的位置 ,明星的位置 6 int flag = 0; 7 8 for (i=1; i<n; i++) 9 { 10 if(a[stari] > a[i])//如果stari标号的数小于i标号的数, 表示a[stari] 认识 a[i] 11 { 12 stari=i; 13 flag=0; //更换怀疑对象(最小数)时,标记清零 14 } 15 else if(a[stari] ==a[i]) //如果stari里存放的确实是唯一最小数是不会跑进这里来的 16 { 17 flag++; 18 } 19 } 20 21 if(flag>0) 22 return -1;//表示没有明星,例如所有的数都相等 23 24 return stari; 25 }
(以上网络代码)
附:
题目:有n-1个群众和1个明星,群众两两间可能认识也可能不认识,但是群众都认识明星,明星不认识其他任何人。现在每次询问一个人是否认识另一个人的时间复杂度是O(1),要求找出明星的时间复杂度。
分析:这是一道老题,关键点在只有一个明星。首先分析一次询问的效果。is A 认识 B? (yes) A不是明星,B可能是明星 : (no) A可能是明星,B是群众。所以一次询问可以确定一个人。总共有n个人,那么当然是O(n)啦。这类时间复杂度的问题一般都有一个O(1)的操作,看看这个操作有什么信息量,就可以很快确定了。
例如,如果一次询问可以知道他认识的人和不认识的人,那么就采用分治的方法了。时间复杂度就是O(log(n)),有这种场景的。
如果有2个明星呢?明星之间互不认识。那么还是O(n),因为找到一个明星之后询问其他所有人,选出不认识的
如果x个呢?当然也是O(n)啦。
P.S. 收到阿里实习电面,所以赶紧翻一下旧账(笔试一塌糊涂,大题准备全要从网上找答案%>_<%)。。。。
毕