格雷码介绍:对于n位二进制码
B
n
−
1
B
n
−
2
.
.
.
B
1
B
0
B_{n-1}B_{n-2}...B_1B_0
Bn−1Bn−2...B1B0所对应的格雷码
G
n
−
1
G
n
−
2
.
.
.
G
2
G
1
G_{n-1}G_{n-2}...G_2G_1
Gn−1Gn−2...G2G1,二者间对应关系为:
G
n
−
1
=
B
n
−
1
G_{n-1}=B_{n-1}
Gn−1=Bn−1,
G
i
=
B
i
⊕
B
i
+
1
G_i=B_i⊕B_{i+1}
Gi=Bi⊕Bi+1(i =0,1…n-2)。其特点为n与(n+1)的格雷码永远只有一位相异,其余各位全部相同。
e.g.二位格雷码:00 -> 00,01 -> 01, 10 -> 11,11 -> 10
对于n位的格雷码,我们想将其转换为(n+1)位格雷码,我们有两种类似思路
1.对每一个n位的格雷码在首位补0,再逆序在首位补1,二者合并形成(n+1)位格雷码
e.g. 00,01,11,10 -> 000,001,011,010 & 110,111,101,100
2.对每一个n位的格雷码,在末位交替补充‘0’/‘1’和‘1’/’0’
e.g. 00,01,11,10 -> 000,001 & 011,010 & 110,111 & 101,100
但是第二种方法更容易运用右移操作实现,所以我们选择第二种方法。
时间复杂度:O(2^N)
C++代码:
class Solution {
public:
vector<int> grayCode(int n) {
if (n == 0)
return {0};
if (n == 1)
return { 0,1 };
else
{
vector<int> result = { 0,1 };
int k = 1;
while (k++ < n)
{
vector<int> temp;
for (int i = 0; i < result.size(); i++)
{
if (i % 2 == 0)
{
temp.push_back(result[i] << 1);
temp.push_back((result[i] << 1) + 1);
}
else
{
temp.push_back((result[i] << 1) + 1);
temp.push_back(result[i] << 1);
}
}
result = vector<int>(move(temp));
}
return result;
}
}
};