1、
在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同, 则称这种编码为格雷码(Gray Code),请编写一个函数,使用递归的方法生成N位的格雷码。
给定一个整数n,请返回n位的格雷码,顺序为从0开始。
测试样例:
1
返回:[“0”,”1”]。
初看题目,已经忘记格雷码的具体规则,题目要求是递归实现。便考虑如何从最简单的一位倒推二位的情况。经过演算总结出如下的规律。N位格雷码都是n-1位格雷码前半部分插零,后半部分插一形成,因此编码实现如下:
class GrayCode {
public:
vector<string> getGray(int n) {
// write code here
vector<string> str;
if (n==1)
{
str.push_back("0");
//str.push_back(",");
str.push_back("1");
return str;
}
else
{
str = getGray(n-1);
vector<string> str1;
str1 = str;
for (int i = str1.size()-1; i >=0; i--)//复制一遍,可能有更好的写法,考虑copy的用法
{
str.push_back(str1[i]);
}
for (int i = 0; i < str.size()/2; i++)
{
str[i].insert(0,"0");
}
for (int i = str.size()/2; i < str.size(); i++)
{
str[i].insert(0, "1");
}
}
return str;
}
};
2.春节期间小明使用微信收到很多个红包,非常开心。在查看领取红包记录时发现,某个红包金额出现的次数超过了红包总数的一半。请帮小明找到该红包金额。写出具体算法思路和代码实现,要求算法尽可能高效。
给定一个红包的金额数组gifts及它的大小n,请返回所求红包的金额。
测试样例:
[1,2,3,2,2],5
返回:2
采用哈希或者类似数组最佳,编程之美有讲,这里做一个简单的实现,当钱数很大时,数组浪费空间巨大,考虑优化,当然在笔试过程中,先考虑功能,在考虑优化。
class Gift {
public:
int getValue(vector<int> gifts, int n) {
// write code here
auto keyMin = minmax_element(gifts.begin(), gifts.end());
int min = *keyMin.first;
int max = *keyMin.second;
vector<int> s(max+1,0);
for (size_t i = 0; i < n; i++)
{
s[gifts.at(i)]++;
}
auto m = max_element(s.begin(), s.end());
if (*m<=n/2)
{
return 0;
}
return m-s.begin();
}
};
import java.util.*;
public class Gift {
public int getValue(int[] gifts, int n) {
Arrays.sort(gifts);
int ans = gifts[n/2];
int num = 0;
for(int i = 0; i < gifts.length; i++) {
if(gifts[i] == ans) {
num++;
}
}
return num <= n/2 ? 0 : ans;
}
}
排序并取中间元素不知道这两个算法该怎么评价,第一个应该是O(n),空间损耗高,第二个O(nlogn),空间可做到O(1)