[编程题] 生成格雷码
时间限制:3秒
空间限制:32768K
在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同, 则称这种编码为格雷码(Gray Code),请编写一个函数,使用递归的方法生成N位的格雷码。
给定一个整数n,请返回n位的格雷码,顺序为从0开始。
测试样例:
1
返回:["0","1"]
import java.util.*;
public class GrayCode {
public String[] getGray(int n) {
// write code here
String[] grayCodeArr = new String[(int)Math.pow(2, n)];
if (n == 1) {
grayCodeArr[0] = "0";
grayCodeArr[1] = "1";
return grayCodeArr;
}
String[] nGrayCodeArr = getGray(n-1);
for(int i=0; i<nGrayCodeArr.length; i++) {
grayCodeArr[i] = "0" + nGrayCodeArr[i];
grayCodeArr[grayCodeArr.length - 1 - i] = "1" + nGrayCodeArr[i];
}
return grayCodeArr;
}
}
[编程题] 微信红包
时间限制:3秒
空间限制:32768K
春节期间小明使用微信收到很多个红包,非常开心。在查看领取红包记录时发现,某个红包金额出现的次数超过了红包总数的一半。请帮小明找到该红包金额。写出具体算法思路和代码实现,要求算法尽可能高效。
给定一个红包的金额数组gifts及它的大小n,请返回所求红包的金额。
若没有金额超过总数的一半,返回0。
测试样例:
[1,2,3,2,2],5
返回:2
分析:有一个红包出现次数超过红包总数的一半,那么很容易想到直接计数,或者排序后最中间的那个值就是答案; 优化方法,可以采用摩尔投票再进行验证,具体是假设res为所求,初始值为gifts[0],num表示次数,初始值为1,依次遍历,如果当前的值等于res,num+1,否则num-1;当num=0时将当前值赋给res,最后验证res出现次数是否大于n/2。
import java.util.*;
public class Main {
public static int getValue(int[] gifts, int n) {
int res = gifts[0];
int num = 1;
for(int i=1; i<n; i++) {
if(num == 0) {
res = gifts[i];
}
if(gifts[i] == res) {
num++;
}else {
num--;
}
}
num = 0;
for(int x: gifts) {
if(x == res) {
num++;
}
}
return (num>n/2) ? res : 0;
}
@SuppressWarnings("resource")
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[] gifts = {1, 3, 2, 2, 2};
System.out.println(getValue(gifts , 5));
}
}