Leetcode#89 Gray Code

原题地址

 

二进制码 -> 格雷码:从最右边起,依次与左边相邻位异或,最左边一位不变。例如:

二进制: 1 0 0 1 1 1 0
|\|\|\|\|\|\|
格雷码: 1 1 0 1 0 0 1

从二进制到格雷码有一个残暴公式: a ^ (a << 1)

 

格雷码 -> 二进制码:从左边第二位开始,依次与左边相邻已经解码位异或,最左边一位不变。例如:

格雷码: 1 1 0 1 0 0 1
1\| | | | | |
1 0 | | | | |
1 0\| | | | |
1 0 0 | | | |
1 0 0\| | | |
1 0 0 1 | | |
1 0 0 1\| | |
1 0 0 1 1 | |
1 0 0 1 1\| |
1 0 0 1 1 1 |
1 0 0 1 1 1\|
1 0 0 1 1 1 0
二进制: 1 0 0 1 1 1 0

可惜从格雷码到二进制没有残暴公式

 

如何从一个格雷码生成下一个格雷码呢?规则如下:

1. 从0开始

2. 翻转最右位(0变1,1变0)

3. 翻转最右边是1的左边那一位,比如100110 -> 100010

4. 回到2

比如要生成4bit的格雷码,按照上面的规则:

步骤  格雷码      编号
1 0 0 0 0 (1)
|
2 0 0 0 1 (2)
|
3 0 0 1 1 (3)
|
2 0 0 1 0 (4)
|
3 0 1 1 0 (5)
|
2 0 1 1 1 (6)
|
3 0 1 0 1 (7)
|
2 0 1 0 0 (8)
|
3 1 1 0 0 (9)
|
2 1 1 0 1 (10)
|
3 1 1 1 1 (11)
|
2 1 1 1 0 (12)
|
3 1 0 1 0 (13)
|
2 1 0 1 1 (14)
|
3 1 0 0 1 (15)
|
2 1 0 0 0 (16)

 

代码:

 1 vector<int> grayCode(int n) {

 2   vector<int> res;

 3   int ub = (1 << n) - 1;

 4   int c = 0;

 5 

 6   for (int i = 0; i <= ub; i++) {

 7     c = (i & 1) ? c ^ 1 : c ^ ((c & -c) << 1);

 8     res.push_back(c);

 9   }

10 

11   return res;

12 }

 

你可能感兴趣的:(LeetCode)