算法整理——2015腾讯开发岗笔试题

来源:互联网 发布:淘宝怎么下架宝贝 编辑:程序博客网 时间:2024/05/23 00:48

春节期间小明使用微信收到很多个红包,非常开心。在查看领取红包记录时发现,某个红包金额出现的次数超过了红包总数的一半。请帮小明找到该红包金额。写出具体算法思路和代码实现,要求算法尽可能高效。


打擂算法:传送门

该算法很好地将一般需要O(nlogn)时间复杂度得到的结果减少成O(n),但是前提条件是出现最多的数的出现次数大于(不包括等于)集合中个数的一半。

float mostElement(vector<float> v){int count = 0;float m;for(int i=0;i<int(v.size());i++){if(count ==0||m == v[i]){m = v[i];count++;}else{count--;}}return m;}


该算法的关键在于count++、count--。假设最多出现次数的值为a,在遍历时,当m==a,遇到新的a会起促进作用;当m!=a时,新的a起消极作用。因为a的个数大于集合个数的一半,到最后时,count一定大于0且m==a。




在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同,则称这种编码为格雷码( Gray Code )。请编写一个函数,使用递归方法生成 N 位的格雷码,并且保证这个函数的健壮性。 


来自维基的解法:传送门

以二进制为0值的格雷码为第零项,第一项改变最右边的位元,第二项改变右起第一个为1的位元的左边位元,第三、四项方法同第一、二项,如此反复,即可排列出n个位元的格雷码。

代码以上面的两步作为一次循环,因为格雷码数m与位数n存在关系 m = 2 ^ n。跳出循环的边界条件是第二项中没有了左边位元。代码健壮性的话,感觉就是所需位数很大时也能正确输出吧。

void grayCode(int n){int* grays = new int[n];for(int i=0; i<n; i++)grays[i]=0;while(1){printGray(grays,n);grays[n-1] = grays[n-1]?0:1;printGray(grays,n);int i = n-1;while(!grays[i])i--;if(i==0)break;grays[i-1] = grays[i-1]?0:1;}}






0 0
原创粉丝点击