# [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/)可很容易地写出代码。

## 思路三（最快）
参考[维基百科](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位元的格雷码以上下镜射后加上新位元的方式快速的得到，如下图所示。    
![graycode](http://upload.wikimedia.org/wikipedia/commons/thumb/c/c1/Binary-reflected_Gray_code_construction.svg/250px-Binary-reflected_Gray_code_construction.svg.png)    
这样就可以用迭代的方式产生格雷码。       



# 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;
    }
};
```

## 思路三
``` 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;
    }
};
```
