题意
给你一个整数数组 perm
,它是前 n
个正整数的排列,且 **n
是个 奇数** 。
它被加密成另一个长度为 n - 1
的整数数组 encoded
,满足
e
n
c
o
d
e
d
[
i
]
=
p
e
r
m
[
i
]
X
O
R
p
e
r
m
[
i
+
1
]
encoded[i] = perm[i] XOR perm[i + 1]
encoded[i]=perm[i]XORperm[i+1] 。比方说,如果 perm = [1,3,2
] ,那么 encoded = [2,1]
。给你 encoded
数组,请你返回原始数组 perm
。题目保证答案存在且唯一。
输入:encoded = [3,1]
输出:[1,2,3]
解释:如果 perm = [1,2,3] ,那么 encoded = [1 XOR 2,2 XOR 3] = [3,1]
题目分析
类似题目 解码异或后的数组。注意区分不同并加以利用:
n
个正整数的排列n
是奇数
并且结合 1720 号题目可知,本题的重点在于求得第一个元素或者最后一个元素。
进行模拟计算
原数组为: p e r m [ 0 ] , p e r m [ 1 ] , . . . , p e r m [ n − 1 ] perm[0],perm[1],...,perm[n-1] perm[0],perm[1],...,perm[n−1]
加密后的数组为: e n c o d e d [ 0 ] , e n c o d e d [ 1 ] , e n c o d e d [ 2 ] , . . . , e n c o d e d [ n − 2 ] encoded[0],encoded[1],encoded[2],...,encoded[n-2] encoded[0],encoded[1],encoded[2],...,encoded[n−2]
计算过程如下:
即encoded
数组所有的偶数项(从第二个元素开始)进行异或运算的结果为,perm
数组除
p
e
r
m
[
0
]
perm[0]
perm[0]元素外其他元素异或的结果,此处记为
x
x
x。
另一方面,perm
数组为前 n
个正整数的排列,因此
p
e
r
m
[
0
]
perm[0]
perm[0]元素为,前 n
个正整数的排列和perm
数组中出现一次的元素。即根据只出现一次的数,将前 n
个正整数和
x
x
x进行异或即可得到
p
e
r
m
[
0
]
perm[0]
perm[0]。
得到 p e r m [ 0 ] perm[0] perm[0]之后,根据解码异或后的数组,进行计算即可。
Code
class Solution {
public int[] decode(int[] encoded) {
int n = encoded.length;
int[] perm = new int[n+1];
//cal x
int x = 0;
for(int i = 1; i < n;) {
x = x ^ encoded[i];
i+=2;
}
// cal first
int first = 0;
for(int i = 1; i <= n+1; i++) {
first = first ^ i;
}
first = first ^ x;
//cal perm
perm[0] = first;
for(int i = 0; i < n; i++) {
perm[i+1] = perm[i] ^ encoded[i];
}
return perm;
}
}