解码异或后的排列
难度:
标签:
题目描述
代码结果
运行时间: 80 ms, 内存: 32.2 MB
/*
* 题目思路:
* 1. 我们通过Stream API来计算totalXor和oddXor。
* 2. 其余步骤和Java解法一致,通过first和encoded解出perm数组。
*/
import java.util.stream.IntStream;
public class Solution {
public int[] decode(int[] encoded) {
int n = encoded.length + 1;
int totalXor = IntStream.rangeClosed(1, n).reduce(0, (a, b) -> a ^ b);
int oddXor = IntStream.range(1, n - 1).filter(i -> i % 2 == 1).map(i -> encoded[i]).reduce(0, (a, b) -> a ^ b);
int first = totalXor ^ oddXor;
int[] perm = new int[n];
perm[0] = first;
IntStream.range(0, n - 1).forEach(i -> perm[i + 1] = perm[i] ^ encoded[i]);
return perm;
}
}
解释
方法:
题解利用了异或运算的性质(自反性:a ^ a = 0和交换律),首先计算出perm数组的最后一个元素。由于perm是前n个正整数的排列,通过异或所有1到n的整数得到b,同时通过异或编码数组中的奇数位置元素得到a。由于n是奇数,perm数组中的奇数位置元素和偶数位置元素分别异或,最终差异将体现在最后一个元素上。因此,通过a ^ b得到perm的最后一个元素。之后,利用encoded数组和已知的perm中的最后一个元素,通过逆向解码还原整个perm数组。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
在解码过程中,为何首先计算perm数组的最后一个元素而不是从第一个元素开始?
▷🦆
在题解中提到通过计算所有奇数位置的异或结果得到变量a,这种选择是基于什么考虑?
▷🦆
解题中提到的计算1到n的所有数字的异或结果(变量b),这个操作是如何确保能与变量a结合来正确还原perm数组的最后一个元素的?
▷🦆
题解中提到利用encoded数组和已知的perm中的最后一个元素逆向解码,能否详细解释逆向解码的步骤和原理?
▷