阿里题目:明星群众问题

阿里的题目:有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. 收到阿里实习电面,所以赶紧翻一下旧账(笔试一塌糊涂,大题准备全要从网上找答案%>_<%)。。。。

posted @ 2013-05-24 16:52  legendmaner  阅读(558)  评论(0编辑  收藏  举报