首页 > 代码库 > [C++]LeetCode: 86 Gray Code (格雷码)
[C++]LeetCode: 86 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.
Answer 1: 映射法
思路:我们通过对格雷码进行观察,发现格雷码具有映射关系。n位元的格雷码可以从n-1位元的格雷码以上下镜射后(一半顺序,一半逆序再加1<<n)加上新位元的方式快速的得到。我们从一个比特位的格雷码开始计算,直到得到N个比特位的格雷码。第一位是 0 + 1<<0, 0 + 1<<1.
Attention:
1.2^n 可以表示为1<<n。
<span style="font-size:14px;"> curNum += (1 << i);</span>2.当n取0时,返回{0},而不是空数组。
<span style="font-size:14px;">vector<int> ret{0};</span>复杂度:O(N^2)
AC Code:
<span style="font-size:14px;">class Solution { public: vector<int> grayCode(int n) { vector<int> ret{0}; for(int i = 0; i < n; i++) { int curCnt = ret.size(); //把当前数字按照逆序顺序添加到ret中 while(curCnt) { curCnt--; int curNum = ret[curCnt]; curNum += (1 << i); ret.push_back(curNum); } } return ret; } };</span>
Answer 2: 二进制转格雷码
思路: 通过对二进制和格雷码的观察,我们得到计算公式:gray = (binary) xor (binary >> 1)。有篇文章有详细解释。
下面我们把二进制数和Gray码都写在下面,可以看到左边的数异或自身右移的结果就等于右边的数。
二进制数 Gray码
000 000
001 001
010 011
011 010
100 110
101 111
110 101
111 100
从二进制数的角度看,“镜像”位置上的数即是对原数进行not运算后的结果。比如,第3个数010和倒数第3个数101的每一位都正好相反。假设这两个数分别为x和y,那么x xor (x shr 1)和y xor (y shr 1)的结果只有一点不同:后者的首位是1,前者的首位是0。而这正好是Gray码的生成方法。这就说明了,Gray码的第n个数确实是n xor (n shr 1)。
Attention:
1. 1 << n位,比特位为n+1位,正好表示n位二进制数+1,如三位二进制最大为7, 1<<3 = 8. 所以可以作为循环条件得到,我们要求的数的范围。
<span style="font-size:14px;">for(int i = 0; i < num; i++)</span>
AC Code:
<span style="font-size:14px;">class Solution { public: vector<int> grayCode(int n) { int num = 1 << n; vector<int> ret; ret.reserve(num); for(int i = 0; i < num; i++) { ret.push_back(i ^ (i >> 1)); } return ret; } };</span>
[C++]LeetCode: 86 Gray Code (格雷码)