关于LeetCode解码异或排列问题的解法困惑与疑问
LeetCode Decode XORed Permutation: 解法错误分析与修正
问题根源
你的解法没有利用题目中perm是前n个正整数的排列这个核心条件,导致计算出的perm[0]不符合要求。虽然你生成的数组能通过XOR还原出encoded,但它不是1到n的排列,因此不符合题目要求。
错误推导细节:
- 你计算的
xor_of_encoded是encoded所有元素的异或,展开后等于perm[0] ^ perm[n-1](中间的perm[1]到perm[n-2]全部抵消)。 xor_without_known_elements是encoded奇数索引元素的异或,展开后是perm[1]^perm[2]^perm[3]^...^perm[n-1]。- 两者异或得到的是
perm[0] ^ perm[n-1] ^ perm[1]^...^perm[n-1] = perm[0] ^ perm[1]^...^perm[n-2],这显然不是perm[0],后续生成的数组自然不是合法排列。
正确思路
因为perm是1到n(n为奇数)的排列,我们可以利用这个条件精准计算perm[0]:
- 计算
total_xor:1到n所有数的异或值(排列的异或和与1~n的异或和完全相同)。 - 计算
odd_encoded_xor:encoded数组中所有奇数索引(i=1,3,5...)元素的异或值,展开后是perm[1]^perm[2]^perm[3]^...^perm[n-1]。 perm[0] = total_xor ^ odd_encoded_xor:total_xor是perm[0]^perm[1]^...^perm[n-1],异或odd_encoded_xor后,perm[1]到perm[n-1]全部抵消,剩下perm[0]。- 有了
perm[0],通过perm[i] = encoded[i-1] ^ perm[i-1]依次推导整个数组即可。
修正后的C++代码
std::vector<int> decode(std::vector<int> encoded) { int n = encoded.size() + 1; int total_xor = 0; // 计算1到n的异或值 for (int i = 1; i <= n; ++i) { total_xor ^= i; } int odd_encoded_xor = 0; // 计算encoded中奇数索引元素的异或 for (int i = 1; i < encoded.size(); i += 2) { odd_encoded_xor ^= encoded[i]; } std::vector<int> perm(n); perm[0] = total_xor ^ odd_encoded_xor; // 推导完整排列 for (int i = 1; i < n; ++i) { perm[i] = encoded[i-1] ^ perm[i-1]; } return perm; }
测试用例验证
- 对于测试用例
[3,1]:- n=3,
total_xor=1^2^3=0 odd_encoded_xor=encoded[1]=1perm[0]=0^1=1,推导得[1,2,3],符合排列要求。
- n=3,
- 对于测试用例
[12,6,11,10,5,3,4,6]:- n=9,
total_xor=1^2^...^9=1 odd_encoded_xor=6^10^3^6=9perm[0]=1^9=8,推导得到的数组是1~9的合法排列。
- n=9,
内容的提问来源于stack exchange,提问作者Szyszka947
相关产品推荐
相关产品推荐

