给你一个整数
n
,返回任一有效的 n 位格雷码序列 。
题目如上。那么什么是格雷编码?以下摘自百度百科:
在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同,则称这种编码为格雷码(Gray Code),另外由于最大数与最小数之间也仅一位数不同,即“首尾相连”,因此又称循环码或反射码。
在数字系统中,常要求代码按一定顺序变化。例如,按自然数递增计数,若采用8421码,则数0111变到1000时四位均要变化,而在实际电路中,4位的变化不可能绝对同时发生,则计数中可能出现短暂的其它代码(1100、1111等)。在特定情况下可能导致电路状态错误或输入错误。使用格雷码可以避免这种错误。格雷码有多种编码形式。
给出例子:
1位格雷编码:00 01 对应[0,1]
2位格雷编码:00 01 11 10 对应[0,1,3,2]
3位格雷编码:000 001 011 010 110 111 101 100 对应[0,1,3,2,6,7,5,4]
……
不难发现,n位格雷编码的前一半编码与(n-1)位编码是一样的。如何用计算机复现这一串编码呢?我有想过用递归,但是过于繁琐,觉得还是应该找规律来解决。以下给出简洁的格雷编码重现:
vector<int> grayCode(int n) {
vector<int> res;
for(int i = 0;i < 1<<n; i++)
{
res.push_back(i ^ i>>1);
}
return res;
}
n位的格雷编码有个,我们用位移符号来计算:1<<n。
除此之外,最重要的,格雷编码如何实现呢?我们以3位格雷编码为例:
0 = 000 = 000 ^ 000 = 0 ^ 0
1 = 001 = 001 ^ 000 = 1 ^ 0
3 = 011 = 010 ^ 001 = 2 ^ 1
2 = 010 = 011 ^ 001 = 3 ^ 1
6 = 110 = 100 ^ 010 = 4 ^ 2
7 = 111 = 101 ^ 010 = 5 ^ 2
5 = 101 = 110 ^ 011 = 6 ^ 3
4 = 100 = 111 ^ 011 = 7 ^ 3
参照如上规律,就可以写出第i位的编码了。