1. 程式人生 > >LeetCode89.Gray Code 格雷編碼

LeetCode89.Gray Code 格雷編碼

這道題看起來很簡單,實際上要求你【每一次編碼的變換不能超過1位】,所以不能直接改變編碼的狀態,否則答案即使對了也會因為答案位置不對而不通過。 愚蠢的我看到這種題目當然想用字串遍歷n遍的方法推出答案。實際上我在寫的過程中隱隱約約的想到了應該用位運算的知識,因為每次code的變換都是左移右移一位,這不剛好符合<<與>>的要求嗎,但是由於自己這方面知識薄弱,還是沒有用這種方法。 下面是我的程式碼。沒有AC,但是答案正確(想必時間複雜度也很高)

class Solution {
public:
    vector<int> grayCode(int n) {
        //給定一個n位編碼長度,然後輸出所有該編碼長度可能的結果
string ss; for(int i=0;i<n;i++) { //統一置為0 ss+='0'; } // cout<<ss<<endl; //多少個結果 int times=pow(2,n); vector<int>ans; for(int i=0;i<times;i++) { int tans=0; // int index=0;
//遍歷字串取出值,加入到tempans中 for(int j=n-1;j>=0;j--) { // cout<<"ss[j]:"<<ss[j]<<endl; if(ss[j]=='1') { tans+=pow(2,abs(j-n+1)); } } //方法有誤! 題目要求的是每次都只能改變一位 按照這種遍歷會不符合規則!
//每次只能改變一位,然後往前遍歷一位! //改變最後一位的狀態 同時往前累進 //進位字串 for(int j=n-1;j>=0;j--) { if(ss[j]=='0') { ss[j]='1'; break; } else { ss[j]='0'; } } // cout<<"chang:"<<ss<<endl; ans.push_back(tans); } return ans; } };

然後看了別人的解答,果然是用位運算,很清晰速度也很快。自己拿筆算了一下。只能說自愧不如。以後要多寫這種位運算的題目了。

class Solution {
public:
    vector<int> grayCode(int n) {
        int N(1 << n), tmp;
        vector<int> result;
        for(int i(0); i < N; i++)
        {
            tmp = i << 1;
            result.push_back((tmp^i) >> 1);
        }
        return result;
    }
};