1734. 解码异或后的排列
题目描述:
给你一个整数数组 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]
提示:
3 <= n < 105
n
是奇数。encoded.length == n - 1
思考:
这个题首先需要具备以下几个知识点:
- 0和任何自然数异或得到的结果都是对方自己,公式 0 ⨁ x = x ( x ! = 0 ) 0 \bigoplus x = x(x != 0) 0⨁x=x(x!=0)
- 若存在 a ⨁ b = c a \bigoplus b = c a⨁b=c,则 a = b ⨁ c a = b \bigoplus c a=b⨁c
- 题目中描述了 n n n为奇数,那么 n − 1 n-1 n−1为偶数
根据题意,数组perm的所有元素是自然数 [ 1 , n ] [1,n] [1,n],那么将 1 ⨁ 2 ⨁ 3 ⨁ . . . ⨁ n 1\bigoplus 2 \bigoplus3 \bigoplus ...\bigoplus n 1⨁2⨁3⨁...⨁n得到的结果 r e s res res就是perm数组所有元素异或的结果。
然后我们画图可以看出
e n c o d e d [ 1 ] = p e r m [ 1 ] ⨁ p e r m [ 2 ] encoded[1] = perm[1] \bigoplus perm[2] encoded[1]=perm[1]⨁perm[2]
e n c o d e d [ 3 ] = p e r m [ 3 ] ⨁ p e r m [ 4 ] encoded[3] = perm[3] \bigoplus perm[4] encoded[3]=perm[3]⨁perm[4]
e n c o d e d [ 5 ] = p e r m [ 5 ] ⨁ p e r m [ 6 ] encoded[5] = perm[5] \bigoplus perm[6] encoded[5]=perm[5]⨁perm[6]
e n c o d e d [ 7 ] = p e r m [ 7 ] ⨁ p e r m [ 8 ] encoded[7] = perm[7] \bigoplus perm[8] encoded[7]=perm[7]⨁perm[8]
观察规律我们可以发现,下标从1开始,每次递增2,将所有这样的 e n c o d e d [ i ] encoded[i] encoded[i]异或得到的结果 a n s ans ans就是 p r e m prem prem数组从下标1开始一直到下标 n − 1 n-1 n−1结束的所有元素异或结果。即
e n c o d e d [ 1 ] ⨁ e n c o d e d [ 3 ] ⨁ e n c o d e d [ 5 ] ⨁ . . . ⨁ e n c o d e d [ n − 2 ] = p e r m [ 1 ] ⨁ p e r m [ 2 ] ⨁ p e r m [ 3 ] ⨁ . . . ⨁ p e r m [ n − 1 ] encoded[1] \bigoplus encoded[3] \bigoplus encoded[5] \bigoplus ... \bigoplus encoded[n-2] = perm[1] \bigoplus perm[2] \bigoplus perm[3] \bigoplus ... \bigoplus perm[n-1] encoded[1]⨁encoded[3]⨁encoded[5]⨁...⨁encoded[n−2]=perm[1]⨁perm[2]⨁perm[3]⨁...⨁perm[n−1]
由于题目中提到n是奇数,因此上式的左边的元素个数一定为偶数个
这样,我们将 r e s ⨁ a n s res \bigoplus ans res⨁ans进行计算得到的结果就是 p r e m [ 0 ] prem[0] prem[0]
再利用我上述提到的第二个知识点“若存在 a ⨁ b = c a \bigoplus b = c a⨁b=c,则 a = b ⨁ c a = b \bigoplus c a=b⨁c”,由 e n c o d e d [ i ] = p r e m [ i ] ⨁ p e r m [ i + 1 ] encoded[i] = prem[i] \bigoplus perm[i+1] encoded[i]=prem[i]⨁perm[i+1]可以得到 p e r m [ i + 1 ] = p e r m [ i ] ⨁ e n c o d e d [ i ] perm[i+1] = perm[i] \bigoplus encoded[i] perm[i+1]=perm[i]⨁encoded[i]
好了,到此此题思路讲述完毕。代码如下展示
class Solution {
public int[] decode(int[] encoded) {
int res = 0;
int ans = 0;
// 实际上perm 的长度要比encoded的长度要多1
int n = encoded.length;
// 这个n + 1计算后得到的n对应题目中描述的n
n = n + 1;
for (int i = 1; i <= n ; i++) {
res ^= i;
}
for (int i = 1; i <= n - 1; i += 2) {
ans ^= encoded[i];
}
int[] arr = new int[n];
arr[0] = res ^ ans;
for (int i = 1; i < n; i++) {
arr[i] = encoded[i-1] ^ arr[i-1];
}
return arr;
}
}