题:
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/17808143aba7b5fc0ce1c0572a680f7c.png)
码+思:
public int[] decode_overTime(int[] encoded) {
// 使用前缀和的思想,使得encoded[i] = perm[0] ^ perm[i+1]
// 因为已知答案唯一,所以第一个数的答案只能是1到n中的一个数,因此暴力解法,直到找到合适的第一个数为止
for(int i = 1 ; i < encoded.length ; i++){
encoded[i] = encoded[i-1]^encoded[i];
}
// 因为encoded[i] = perm[0] ^ perm[i+1],所以 perm[i+1] = encoded[i] ^ perm[0]
// 固定perm[0]以后,求解其他的数,并加入到set中,如果出现重复数字,说明这个perm[0]不行
// 如果计算的perm[i+1]小于1或者大于perm.length 也不行
// --------超出时间限制-------
Set set = new HashSet<>();
int[] ans = null;
for(int i = 1 ; i < encoded.length+2 ; i++){
int[] perm = new int[encoded.length+1];
perm[0] = i;
set.add(i);
int j;
for(j = 1 ; j < perm.length ; j++){
perm[j] = perm[0] ^ encoded[j-1];
if(set.contains(perm[j])||perm[j]>perm.length||perm[j]<1){
set.clear(); // 清空set
break;
}
}
if(j == perm.length){
ans = perm;
break;
}
}
return ans;
}
结果:超出时间限制
优化后的码+思:
public int[] decode(int[] encoded){
/*
优化思路:
现在是暴力解法,找到一个合适的perm[0] 使得题目所要求成立,但实际上,perm[0]可以直接求得
因为对于原始的encoded而言,encoded[1]^encoded[3]^...^encoded[n-2] = perm[1]^perm[2]^perm[3]^...^perm[n-1]
n为奇数!所以n-2必为奇数
假设处理后的Sum(term[0~n-1])为total
则total = perm[0]^perm[1]^perm[2]^perm[3]^...^perm[n-1] = perm[0] ^ encoded[1]^encoded[3]^...^encoded[n-2]
于是有perm[0] = total ^ encoded[1]^encoded[3]^...^encoded[n-2]
而事实上 total是已经给定的,即total == 1 ^ 2 ^...^ n
*/
int n = encoded.length+1;
int total = 1;
for(int i = 2 ; i <= n ; i++){
total ^= i;
}
int[] perm = new int[n];
perm[0] = total;
for(int i = 1;i<=n-2;i+=2){
perm[0] ^= encoded[i];
}
// 求encoded前缀和
for(int i = 1 ; i < encoded.length ; i++){
encoded[i] = encoded[i-1]^encoded[i];
}
// 求perm所有值
for(int i = 1 ; i < n ; i++){
perm[i] = encoded[i-1] ^ perm[0];
}
return perm;
}