题目链接:Gray Code
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.
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位格雷码。
在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同,则称这种编码为格雷码(Gray Code),另外由于最大数与最小数之间也仅一位数不同,即“首尾相连”,因此又称循环码或反射码。在数字系统中,常要求代码按一定顺序变化。例如,按自然数递增计数,若采用8421码,则数0111变到1000时四位均要变化,而在实际电路中,4位的变化不可能绝对同时发生,则计数中可能出现短暂的其它代码(1100、1111等)。在特定情况下可能导致电路状态错误或输入错误。使用格雷码可以避免这种错误。格雷码有多种编码形式。
格雷码(Gray Code)曾用过Grey Code、葛莱码、格莱码、戈莱码、循环码、反射二进制码、最小差错码等名字,它们有的不对,有的易与其它名称混淆,建议不要再使用这些曾用名。
直接排列
以二进制为0值的格雷码为第零项,第一项改变最右边的位元,第二项改变右起第一个为1的位元的左边位元,第三、四项方法同第一、二项,如此反复,即可排列出n个位元的格雷码。
镜射排列
n位元的格雷码可以从n-1位元的格雷码以上下镜射后加上新位元的方式快速的得到。这种方法基于格雷码是反射码的事实,利用递归的如下规则来构造:
- 1位格雷码有两个码字
- (n+1)位格雷码中的前2^n个码字等于n位格雷码的码字,按顺序书写,加前缀0
- (n+1)位格雷码中的后2^n个码字等于n位格雷码的码字,按逆序书写,加前缀1
二进制数转格雷码
(假设以二进制为0的值做为格雷码的0)
G:格雷码 B:二进制码
G(N) = (B(n)/2) XOR B(n)
格雷码转二进制数
二进制码第n位 = 二进制码第(n+1)位+格雷码第n位。因为二进制码和格雷码皆有相同位数,所以二进制码可从最高位的左边位元取0,以进行计算。(注:遇到1+1时结果视为0)
例如: 格雷码0111,为4位数,所以其所转为之二进制码也必为4位数,因此可取转成之二进制码第五位为0,即0 b3 b2 b1 b0。
0+0=0,所以b3=0
0+1=1,所以b2=1
1+1取0,所以b1=0
0+1取1,所以b0=1
因此所转换为之二进制码为0101。
参考自维基百科。
最后
此题要求生成n位格雷码,共计有2^n个。根据上面公式G(N) = B(n) XOR (B(n)/2),即可逐步生成所有格雷码。
时间复杂度:O(2^n)
空间复杂度:O(2^n)
1 class Solution
2 {
3 public:
4 vector<int> grayCode(int n)
5 {
6 vector<int> v;
7 for(int i = 0; i < 1 << n; ++ i)
8 v.push_back(i ^ i >> 1);
9 return v;
10 }
11 };