2019-03-21 06:50:31 +00:00
|
|
|
|
# [89. Gray Code](https://leetcode.com/problems/gray-code/)
|
|
|
|
|
# 思路
|
|
|
|
|
## 思路一
|
|
|
|
|
就按照题目的意思进行模拟,用数组res和一个set来记录已经产生的结果,我们从0开始,遍历其二进制每一位,对其取反,
|
|
|
|
|
然后看其是否在set中出现过,如果没有,我们将其加入set和结果res中,然后再递归对这个数进行刚刚的操作,这样就可以得到所有的格雷码了。
|
|
|
|
|
|
|
|
|
|
## 思路二
|
|
|
|
|
如果对格雷码(可参考[维基百科](https://zh.wikipedia.org/wiki/%E6%A0%BC%E9%9B%B7%E7%A0%81))熟悉的话这题其实就是将二进制转换为格雷码,
|
|
|
|
|
举个例子,3位的格雷码和二进制如下所示:
|
|
|
|
|
```
|
|
|
|
|
Int Grey Code Binary
|
|
|
|
|
0 000 000
|
|
|
|
|
1 001 001
|
|
|
|
|
2 011 010
|
|
|
|
|
3 010 011
|
|
|
|
|
4 110 100
|
|
|
|
|
5 111 101
|
|
|
|
|
6 101 110
|
|
|
|
|
7 100 111
|
|
|
|
|
```
|
|
|
|
|
参考维基百科及[这篇博客](http://www.omegaxyz.com/2017/11/16/grayandbi/)可很容易地写出代码。
|
|
|
|
|
|
2019-03-21 15:35:37 +00:00
|
|
|
|
## 思路三(最快)
|
|
|
|
|
参考[维基百科](https://zh.wikipedia.org/wiki/%E6%A0%BC%E9%9B%B7%E7%A0%81#%E9%8F%A1%E5%B0%84%E6%8E%92%E5%88%97)我们知道,格雷码是按照镜面排列的,n位元的格雷码可以从n-1位元的格雷码以上下镜射后加上新位元的方式快速的得到,如下图所示。
|
|
|
|
|

|
|
|
|
|
这样就可以用迭代的方式产生格雷码。
|
|
|
|
|
|
2019-03-21 06:50:31 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# C++
|
|
|
|
|
## 思路一
|
|
|
|
|
``` C++
|
|
|
|
|
class Solution {
|
|
|
|
|
private:
|
|
|
|
|
void helper(vector<int> &res, set<int> &s, int code, int n){
|
|
|
|
|
s.insert(code);
|
|
|
|
|
res.push_back(code);
|
|
|
|
|
|
|
|
|
|
for(int i = 0; i < n; i++){
|
|
|
|
|
int mask = (1 << i);
|
|
|
|
|
int t = code;
|
|
|
|
|
if((t & mask) == 0) // 第i位是0
|
|
|
|
|
t |= mask; // 把第i位变成1
|
|
|
|
|
else // 第i位是1
|
|
|
|
|
t &= ~mask; // 把第i位变成0
|
|
|
|
|
if(s.count(t)) continue;
|
|
|
|
|
helper(res, s, t, n);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public:
|
|
|
|
|
vector<int> grayCode(int n) {
|
|
|
|
|
vector<int> res;
|
|
|
|
|
set<int>s;
|
|
|
|
|
helper(res, s, 0, n);
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
```
|
|
|
|
|
## 思路二
|
|
|
|
|
``` C++
|
|
|
|
|
class Solution {
|
|
|
|
|
public:
|
|
|
|
|
vector<int> grayCode(int n) {
|
|
|
|
|
vector<int> res;
|
|
|
|
|
for (int i = 0; i < pow(2,n); ++i) {
|
|
|
|
|
res.push_back((i >> 1) ^ i); // ^ 是异或的意思
|
|
|
|
|
}
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
```
|
2019-03-21 15:35:37 +00:00
|
|
|
|
|
|
|
|
|
## 思路三
|
|
|
|
|
``` C++
|
|
|
|
|
class Solution {
|
|
|
|
|
public:
|
|
|
|
|
vector<int> grayCode(int n) {
|
|
|
|
|
vector<int>res;
|
|
|
|
|
res.push_back(0);
|
|
|
|
|
for(int i = 0; i < n; i++){
|
|
|
|
|
int size = res.size();
|
|
|
|
|
for(int j = 0; j < size; j++)
|
|
|
|
|
res.push_back(res[size - j - 1]);
|
|
|
|
|
for(int j = 0; j < res.size(); j++){
|
|
|
|
|
res[j] = res[j] | ((j / size) << i); // 在左边添加一半的0和一半的1
|
|
|
|
|
// res[j] = (res[j] << 1) | (j / size); // 在右边添加一半的0和一半的1
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
```
|