题目:
The gray code is a binary numeral system where two successive values differ in only one bit.
Given a non-negative integer n representing the total number of bits in the code, print the sequence of gray code. A gray code sequence must begin with 0.
格雷码是一个二进制数字系统,两个连续的数字的二进制数字只有一位不同。
给定一个非负整数n,代表格雷码的二进位的个数,输出格雷码序列。格雷码序列必须以0开头。
For example, given n = 2, return [0,1,3,2]
. Its gray code sequence is:
00 - 0 01 - 1 11 - 3 10 - 2
Note:
For a given n, a gray code sequence is not uniquely defined.
For example, [0,2,3,1]
is also a valid gray code sequence according to the above definition.
For now, the judge is able to judge based on one instance of gray code sequence. Sorry about that.
对于给定的数字n,格雷码不是唯一的。
思路:
自然二进制码转换为格雷码:g 0 = b 0 , g i = b i ⊕ b i − 1
保留自然二进制码的最高位作为格雷码的最高位(首位),格雷码次高位为二进制码的高位与次高位异或,其余各位与次高位的求法类似。例如,将自然二进制码1001,转换为格雷码的过程是:保留最高位;然后将第1 位的1 和第2 位的0 异或,得到1,作为格雷码的第2 位;将第2 位的0 和第3 位的0 异或,得到0,作为格雷码的第3 位;将第3 位的0 和第4 位的1 异或,得到1,作为格雷码的第4 位,最终,格雷码为1101。
格雷码转换为自然二进制码:b 0 = g 0 , b i = g i ⊕ b i − 1
保留格雷码的最高位作为自然二进制码的最高位,次高位为自然二进制高位与格雷码次高位异或,其余各位与次高位的求法类似。例如,将格雷码1000 转换为自然二进制码的过程是:保留最高位1,作为自然二进制码的最高位;然后将自然二进制码的第1 位1 和格雷码的第2 位0 异或,得到1,作为自然二进制码的第2 位;将自然二进制码的第2 位1 和格雷码的第3 位0 异或,得到1,作为自然二进制码的第3 位;将自然二进制码的第3 位1 和格雷码的第4 位0 异或,得到1,作为自然二进制码的第4 位,最终,自然二进制码为1111。
格雷码有数学公式,整数 n 的格雷码是 n ⊕ ( n/2)。(实际是由n的自然二进制码转换为格雷码,然后由格雷码转换为十进制数,比如上面的1001->1101)
这题要求生成 n 比特的所有格雷码。
方法 1,最简单的方法,利用数学公式,对从0 ∼ 2 ^n − 1 的所有整数,转化为格雷码。
方法 2,n 比特的格雷码,可以递归地从n − 1 比特的格雷码生成。
这种方法基于格雷码是反射码的事实,利用递归的如下规则来构造:
1位格雷码有两个码字
(n+1)位格雷码中的前2^n个码字等于n位格雷码的码字,按顺序书写,加前缀0
(n+1)位格雷码中的后2^n个码字等于n位格雷码的码字,按逆序书写,加前缀1
代码1(公式法):
class Solution {
public:
//整数 n 的格雷码是 n ⊕ ( n/2)
vector<int> grayCode(int n)
{
int num = 1 << n;
vector<int> result;
for(int i = 0 ; i < num ; i++)
{
result.push_back(i ^ (i >> 1));
}
return result;
}
};
代码2:
2位格雷码 | 3位格雷码 | 4位格雷码 | 4位自然二进制码 |
---|---|---|---|
00
01
11
10
|
000
001
011
010
110
111
101
100
|
0000
0001
0011
0010
0110
0111
0101
0100
1100
1101
1111
1110
1010
1011
1001
1000
|
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111
|
class Solution {
public:
vector<int> grayCode(int n)
{
vector<int> result;
result.push_back(0);
for (int i = 0; i < n; i++)
{
const int highest_bit = 1 << i;//2^i位的前2^(i-1)位不需要改变,后2^(i-1)位为用1<<i与前2^(i-1)位的逆序取或
for (int j = result.size() - 1; j >= 0; j--) // 要反着遍历,才能对称
{
result.push_back(highest_bit | result[j]);
}
}
return result;
}
};