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.
题目解析:
方案一:纯数学计算
找到格雷码的顺序。相邻的两个只有一位不相等。
1、两个数按位异或—相同为0,不同为1。
2、判断二进制中是否只有一个1,用《二进制中1的个数》中的方法,tmp & (tmp-1) —-如果为0,代表只有一个1。
class Solution {
public:
vector<int> grayCode(int n) {
vector<int> res;
int num = Exponent(n);
for(int i = 0;i < num;i++)
res.push_back(i);
GenerateGrayCode(res,0);
return res;
}
//调整顺序,找到与res[index]相邻接的下一个数,然后递归调用。
void GenerateGrayCode(vector<int> &res,int index){
int len = res.size();
if(index>=len-1) //退出循环条件
return ;
int i;
for(i = index+1;i < len;i++){ //找到位置i
int tmp = (res[index] ^ res[i]);
if((tmp & (tmp-1)) == 0)
break;
}
int temp = res[i]; //平移一位,然后将第i位移到index+1的位置
for(int j = i;j > index+1;j--)
res[j] = res[j-1];
res[index+1] = temp;
GenerateGrayCode(res,index+1);
}
int Exponent(int n){ //计算2^n
if(n<=0)
return 1;
if(n == 1)
return 2;
int k = Exponent(n/2);
if(n%2 == 0)
return k * k;
else
return 2 * k * k;
}
};
方案二:格雷码特性
递归生成码表
这种方法基于格雷码是反射码的事实,利用递归的如下规则来构造:
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 |
例如:n=1时,只有两个0、1。n=2时,前两位和之前的相同,后两位在高位增加一位,写上1,低位是前面的逆序。
比如n=3:000–001 || 011–010 |||| 110–111 || 101–100
有了这个特性,就能写出如下代码:
vector<int> grayCode(int n) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
vector<int> res;
res.push_back(0);
int highbit = 0;
while(n--)
{
highbit = res.size();
for(int i= res.size()-1; i >= 0; i--)
res.push_back(highbit|res[i]);
}
return res;
}
方案三:数学方法
从第0个开始,第i个gray code为:(i>>1)^i
vector<int> grayCode(int n) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
vector<int> res;
int num = 1<<n;
int i = 0;
while(i<num)
res.push_back((i>>1)^(i++));
return res;
}