思路:一开始没有想那么多,没有把条件n是个奇数利用起来。
最开始的做法是暴力,直接循环查找+回溯,意料之中的超时,一边写一边都觉得时间复杂度太高了。
class Solution {
vector<int> result;
map<int,int> mp;
bool Find(vector<int>& encoded,int sit)
{
if(sit>encoded.size()) return true;
for(int i=1;i<=encoded.size()+1;++i)
{
if(mp[i]==1) continue;
if((result[sit-1]^i)==encoded[sit-1])
{
result.push_back(i);
mp[i]=1;
if(Find(encoded,sit+1)) return true;
result.pop_back();
mp[i]=0;
}
}
return false;
}
public:
vector<int> decode(vector<int>& encoded) {
for(int i=1;i<=encoded.size()+1;++i)
{
result.push_back(i);
mp[i]=1;
if(Find(encoded,1)) return result;
result.pop_back();
mp[i]=0;
}
return result;
}
};
然后看了官方解答,就用到了n为奇数这一条件,可以先求出perm所有元素的异或,再求出perm元素中除了perm[0]之外的所有元素异或,由于a⊕a=0和 a⊕0=a,可以将两结果异或后求得perm[0],有了perm[0]其余数字就很好求了:perm[n]perm[n+1]=encoded[n],两边同时异或个perm[n]就可以求得:perm[n+1]=perm[n]encoded[n];
class Solution {
public:
vector<int> decode(vector<int>& encoded) {
int sum=1;
//perm所有元素的异或结果
for(int i=2;i<=encoded.size()+1;++i)
sum=sum^i;
//再与perm除perm[0]元素外所有元素的异或得到perm[0]
for(int i=1;i<encoded.size();i=i+2)
sum=(sum^encoded[i]);
vector<int> perm;
perm.push_back(sum);
for(int i=0;i<encoded.size();++i)
{
perm.push_back(perm[i]^encoded[i]);
}
return perm;
}
};