1.我们先来看一下什么是格雷码
Gray Code是一个数列集合,每个数使用二进制来表示,假设使用n位元来表示每个数字,那么任两个数之间只有一个位元值不同。
log2(16)=4 例如: 生成4位元的格雷码就是: 0000 0001 0011 0010 0110
0111 0101 0100 1100 1101 1111 1110 1010 1011 1001 1000
G
ray Code的顺序并不是唯一的,可以是上面的所形成的数列的任意一种。Gray Code是由贝尔实验室的Frank Gray在1940年代提出的,用来在使用PCM(Pusle Code Modulation)方法传送讯号时避免出错,并于1953年三月十七日取得美国专利。如果要产生n位的格雷码,那么格雷码的个数为2^n个
2.必会笔试题
问题: 利用递归实现求n位所有格雷码
解题技巧:
我们一上来可能被题吓了一跳,觉得这是一个很难的题,
当我们冷静分析:
1位格雷码:
0
1
2位格雷码
00
01
11
10
3位格雷码
000
001
011
010
110
111
101
100
不难发现:
2位格雷码是由1位格雷码前面加0和1,并且是除了第一位其他位都对称
3位格雷码是由2位格雷码前面加0和1,并且是除了第一位其他位都对称
因此可以用到递归:
n位格雷码 [ i ] = “0” + n-1位格雷码 [ i ]
n位格雷码[2^n-i-1]=“1”+n-1位格雷码[ i ]
由此写得代码:
public String[] getGray(int n) {
//定义一个保存结果的数组,大小为2的n次方
String[] strs = new String[(int)Math.pow(2,n)];
if(n == 1){ //如果n为1,直接赋值返回结果即可
strs[0] = "0";
strs[1] = "1";
return strs;
}
//如果不为1,开始递归逻辑,求n首先求n-1,求n-1首先求n-2,.....最终递归到1,开始返回,最终得到结果n
//每次递归的过程都会用到下面的循环给前一位的格雷码前面加0加1,得到本次所求格雷码
String[] str = getGray(n-1);
for (int i = 0; i < str.length; i++) {
strs[i] = "0" + str[i];
strs[strs.length-i-1] = "1" + str[i];
}
return strs;
}