这道题看起来很简单,实际上要求你【每一次编码的变换不能超过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;
}
};