腾讯2016研发工程师编程题

来源:互联网 发布:ubuntu移动文件 编辑:程序博客网 时间:2024/06/10 23:48

1.生成格雷码
在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同, 则称这种编码为格雷码(Gray Code),请编写一个函数,使用递归的方法生成N位的格雷码。
给定一个整数n,请返回n位的格雷码,顺序为从0开始。
测试样例:
1
返回:[“0”,”1”]
想法:
考点是递归。n = 1时,[“0”,”1”]
下一次递归 是在前一次的结果基础上,对称分配,最开始以为分别是0和1.

class GrayCode {public:    vector<string> getGray(int n) {        // write code here        vector<string> Gray;        if(n == 0)            return Gray;        if(n == 1){            Gray.push_back("0");            Gray.push_back("1");            return Gray;        }        vector<string> gray = getGray(n-1);        vector<string>::iterator it;        int count = 0;        for(it = gray.begin(); it!= gray.end(); it++){            Gray.push_back("0"+*it);            count ++;        }        count --;        for(int i = count; i>=0; i--){            Gray.push_back("1"+gray[i]);        }        return Gray;    }};

2.微信红包
春节期间小明使用微信收到很多个红包,非常开心。在查看领取红包记录时发现,某个红包金额出现的次数超过了红包总数的一半。请帮小明找到该红包金额。写出具体算法思路和代码实现,要求算法尽可能高效。
给定一个红包的金额数组gifts及它的大小n,请返回所求红包的金额。
测试样例:
[1,2,3,2,2],5
返回:2
这个题考点是查找,而且我自己感觉都用不到二分查找,因为要找的是某个数在数组中出现次数过半,因此排序一遍之后数组中间的一定是所要求的次数过半的数字。当然,如果所有数字的出现次数都没有过半,那么中间这个数字是不符合条件的。

 #include<algorithm> class Gift {public:    int getValue(vector<int> gifts, int n) {        // write code here        if(gifts.empty()||n<=0)            return -1;        sort(gifts.begin(),gifts.end());        int mid = (n-1)>>1;        int key = gifts[mid];        int start = 0,end = gifts.size()-1;        while(gifts[start]<key)            start ++;        if(gifts[start]!= key)//start 从前往后找key的第一个出现            return -1;        while(gifts[end]!= key)//end 从后往前找key最后一个出现            end--;        if(gifts[end]!=key)            return -1;        int count = end-start+1;        if(count >n/2)            return key;        else            return 0;    }};

这个题在编程之美上有一道类似的题,但是不一样。
水往那道题假设一定有超过一半的数字出现,这样就可以按照这种

class Gift {public:    int getValue(vector<int> gifts, int n) {        // write code here        int candidate = -1;        int nTimes = 0;        int N = gifts.size();        for(int i = 0;i<N; i++){            if(nTimes == 0){                candidate = gifts[i];                nTimes = 1;            }else{                if(candidate == gifts[i]){                    nTimes ++;                }else                    nTimes --;            }        }        if(nTimes>0)            return candidate;        else            return 0;    }};

这里面可以看作是打怪兽,每碰见一次己方,加一滴血,碰见一次对方,掉一滴血。因为水王是人数最多的,所以最后剩下的一定是水王。但是如果没有超过一半的。比如[3,3,3,2,2,2,1],按照这个程序最后返回的是1,而1是次数最少的一个。怎么用这种思维改一下呢?

0 0