LeetCode89.Gray Code 格雷編碼
阿新 • • 發佈:2018-12-15
這道題看起來很簡單,實際上要求你【每一次編碼的變換不能超過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;
}
};