1. 程式人生 > 其它 >LeetCode/格雷編碼

LeetCode/格雷編碼

n 位格雷碼序列 是一個由 2n 個整陣列成的序列,其中:

  • 每個整數都在範圍 [0, 2n - 1] 內(含 0 和 2n - 1)
  • 第一個整數是 0
  • 一個整數在序列中出現 不超過一次
  • 每對 相鄰 整數的二進位制表示 恰好一位不同 ,且
  • 第一個 和 最後一個 整數的二進位制表示 恰好一位不同

給你一個整數 n ,返回任一有效的 n 位格雷碼序列

1.回溯法(超時)

回溯法
class Solution {
public:
    //應該是異或運算結果是2的n次冪
    unordered_set<int> map_;
    bool cut = false;
    vector<int> grayCode(int n) {
        for(int i=0;i<n;i++) map_.insert(pow(2,i));
        int num = pow(2,n);
        vector<bool> flag(num,false);
        vector<int> Code;
        backtrack(Code,0,flag,num);
        return Code;
    }
    void backtrack(vector<int>&list,int index,vector<bool>flag,int num){

        if(index==num){cut=true;return;}
        for(int i=0;i<num;i++){
            if(index==0||(!flag[i]&&map_.count(i^list[index-1]))){
                if(index==num-1&&!map_.count(i^list[0])) continue;
            list.push_back(i);
            flag[i]=true;
            backtrack(list,index+1,flag,num);
            if(cut) break;
            list.pop_back();
            flag[i]=false;
            }
        }
    }
};

2.格雷碼公式

class Solution {
public:
    vector<int> grayCode(int n) {
        vector<int> ret(1 << n);
        for (int i = 0; i < ret.size(); i++) {
            ret[i] = (i >> 1) ^ i;
        }
        return ret;
    }
};

3.映象反轉

class Solution {
public:
    vector<int> grayCode(int n) {
        vector<int> ret;
        ret.reserve(1 << n);
        ret.push_back(0);
        for (int i = 1; i <= n; i++) {
            int m = ret.size();
            for (int j = m - 1; j >= 0; j--) {
                ret.push_back(ret[j] | (1 << (i - 1)));
            }
        }
        return ret;
    }
};