腾讯2016研发工程师编程题

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
 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]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;iif(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是次数最少的一个。怎么用这种思维改一下呢?

你可能感兴趣的:(笔试题)