给你一个整数数组 perm ,它是前 n 个正整数的排列,且 n 是个 奇数 。
它被加密成另一个长度为 n - 1 的整数数组 encoded ,满足 encoded[i] = perm[i] XOR perm[i + 1] 。比方说,如果 perm = [1,3,2] ,那么 encoded = [2,1] 。
给你 encoded 数组,请你返回原始数组 perm 。题目保证答案存在且唯一。
示例 1:
输入:encoded = [3,1]
输出:[1,2,3]
解释:如果 perm = [1,2,3] ,那么 encoded = [1 XOR 2,2 XOR 3] = [3,1]
示例 2:
输入:encoded = [6,5,4,6]
输出:[2,4,1,5,3]
补充位运算的性质
- a ^ x ^x=a (对一个数进行两次相同的异或,其值不变)
- 异或运算满足交换律: a^c ^d ^e ^b=a ^b ^c ^d ^e
- a^0=a
思路:考察的就是位运算的性质,做这题的时候,忘了一个,so,gg了,
正确思路:endcode数组里的元素是由perm[i]^perm[i+1]所得,所以我们只需找到一个perm[i]我们就可以利用位运算的第1个性质找到perm[i+1],继而迭代找到剩下的元素
假设
prem={a,c,b}
endcode={a ^ c ,c ^ b}
我们可以找到prem[0]=a=a^ (c ^ b) ^ (c ^ b)
(c ^ b)我们很容易得到:及endcode数组的偶数项
但a^ (c ^ b)我们如何得到呢?----->实际上这里就需要用到第2个性质交换律a^c ^b==a ^b ^c
我们知道有n个数,那么原数组的异或和我们就知道了
代码:
class Solution {
public int[] decode(int[] encoded) {
int [] ans=new int[encoded.length+1];
int temp1=0;//原数组的异或和
for(int i=1;i<=encoded.length+1;i++){
temp1=temp1^i;
}
int temp=0;// 除第一个以外的异或和
for(int i=1;i<=encoded.length-1;i+=2){
temp=temp^encoded[i];
}
int first=temp1^temp;
ans[0]=first;
for(int i=1;i<=encoded.length;i++){
ans[i]=ans[i-1]^encoded[i-1];
}
return ans;
}
}