链接
https://leetcode-cn.com/problems/decode-xored-permutation/
耗时
解题:1 h 15 min
题解:41 min
题意
给你一个整数数组 perm
,它是前 n
个正整数的排列,且 n
是个 奇数 。
它被加密成另一个长度为 n - 1
的整数数组 encoded
,满足 encoded[i] = perm[i] XOR perm[i + 1]
。比方说,如果 perm = [1,3,2]
,那么 encoded = [2,1]
。
给你 encoded
数组,请你返回原始数组 perm
。题目保证答案存在且唯一。
提示:
3 <= n < 105
n
是奇数。encoded.length == n - 1
思路
根据题意 perm[] 是前 n
个正整数的排列,所以 perm[0] ~ perm[n-1] 一定分别是 1~n 中的某一个数,并且没有相同的数。
n
是个 奇数,那么,设 n = 2k+1
encoded[i] = perm[i] XOR perm[i + 1]
,将 encoded[]
写全,则
encoded[] = {perm[0] XOR perm[1], perm[1] XOR perm[2], perm[2] XOR perm[3], …, perm[2k-2] XOR perm[2k-1], perm[2k-1] XOR perm[2k]}
,encoded[]
一共 2k 个元素。
观察 encoded[]
数组可以发现,encoded[]
数组的偶数的位置正好是无重复的 perm[0]~perm[2k],将 encoded[]
偶数位置的元素异或,即可得到 perm[0] XOR ... XOR perm[2k-1]
即 perm[0] XOR ... XOR perm[n-2]
,perm[] 数组的 第一个元素 异或到 倒数第二个元素。然后我们又已知 perm[0] ~ perm[n-1] 一定分别是 1~n 中的某一个数,所以 perm[0] XOR ... XOR perm[n-1]
= 1 XOR ... XOR n
。
综上,可以得到 perm[n-1]
= 1 XOR ... XOR n
XOR perm[0] XOR ... XOR perm[2k-1]
,即 perm[] 数组的最后一位元素可以通过 1 XOR ... XOR n
异或 encoded[]
偶数位置的元素异或值 得到。
得到 perm[] 的最后一位元素之后就好办了,遍历 encoded[],迭代地向前异或即可得到 perm[]。
获取公式:perm[i]=perm[i+1] XOR encoded[i]
。
时间复杂度: O ( n ) O(n) O(n)
AC代码
class Solution {
public:
vector<int> decode(vector<int>& encoded) {
int n = encoded.size()+1;
int x = 0;
for(int i = 1; i <= n; ++i) {
x ^= i;
}
for(int i = 0; i < n-1; ++i) {
if(i&1) continue;
x ^= encoded[i];
}
vector<int> perm(n);
perm[n-1] = x;
for(int i = n-2; i >= 0; --i) {
perm[i] = perm[i+1]^encoded[i];
}
return perm;
}
};