看到的貌似是阿里的笔试题,题意是一组数,要找到min和max,同时要求时间复杂度(比较次数)小于2n(2n的办法都想得到)。
别人的思路:n个数的数组里看作每两个一组,若n是奇数,最后个单独看。
然后遍历一次,找出每组数里的tmax和tmin,tmax存到一个数组,tmin存到一个数组,此时比较次数为n/2;
可知最大数在max数组里,最小数在min数组里,再用普通线性比较分别遍历两个数组 找到max数组里的最大,min数组里的最小即可比较次数为n/2,n/2
总共为n/2+n/2+n/2=3n/2;再对max和min数组用同样办法和直接求无差别。
ps:空间上还可以继续优化下,维护两个gmax,gmin,在每次对每组数找tmax和tmin时,tmax直接和gmax比较 tmin和gmin,随时更新
这样就不用额外的数组了,或者在原数组里交换位置,让tmax总在右边也可..
1 void fmm(int *arry,int len) 2 { 3 int gmax,gmin; 4 for(int i=0;i<len;i+=2) 5 { 6 7 int tmax,tmin; 8 arry[i]>arry[i+1]?tmax=arry[i],tmin=arry[i+1]:tmax=arry[i+1],tmin=arry[i]; 9 if(i==0) 10 gmax=tmax,gmin=tmin; 11 else 12 { 13 gmax=gmax>tmax?gmax:tmax; 14 gmin=gmin<tmin?gmin:tmin; 15 } 16 } 17 18 if(len%2) 19 { 20 gmax=gmax>arry[len-1]?gmax:arry[len-1]; 21 gmin=gmin<arry[len-1]?gmin:arry[len-1]; 22 } 23 cout<<gmax<<":"<<gmin<<endl; 24 }