解码 XOR 排列的结果总是唯一的,这是真的吗?

Is that true that result of decoding XORed permutation will always be unique?

提问人:Szyszka947 提问时间:11/13/2023 最后编辑:OuroborusSzyszka947 更新时间:11/14/2023 访问量:100

问:

我正在为 LeetCode 任务而苦苦挣扎:解码 XOR 排列

有一个整数数组 perm,它是前 n 个的排列 正整数,其中 n 总是奇数。

它被编码到另一个编码长度为 n - 1 的整数数组中, 使得 encoded[i] = perm[i] XOR perm[i + 1]。例如,如果 perm = [1,3,2],然后编码 = [2,1]。

给定编码的数组,返回原始数组 perm。是的 保证答案存在并且是唯一的。

我想这样解决它:

  1. 对编码数组的所有元素进行异或。让我们命名它X
  2. 对位于偶数位置的编码数组的元素进行异或(因此我删除了生成的排列数组中除第一个元素之外的所有元素)。让我们命名它Y
  3. 我这样做了,这是我在排列数组中的第一个元素。X xor Y

如果我知道第一个元素,我可以轻松解决整个问题。 代码如下:

std::vector<int> decode(std::vector<int> encoded) {
    int xor_of_encoded = 0;
    int xor_without_known_elements = 0;
    for (int i = 0; i < encoded.size(); i++) {
        xor_of_encoded ^= encoded[i];
        if (i % 2 == 1)
            xor_without_known_elements ^= encoded[i];
    }

    std::vector<int> decoded(encoded.size() + 1);
    decoded[0] = xor_of_encoded ^ xor_without_known_elements;

    for (int i = 1; i <= encoded.size(); i++) {
        decoded[i] = (encoded[i - 1] ^ decoded[i - 1]);
    }

    return decoded;
}

其工作原理的可视化表示:

   6   5   4   6         <-- encoded
   |   |   |   |
   Ʌ   Ʌ   Ʌ   Ʌ
  / \ / \ / \ / \
 |   V   V   V   |
 |   |   |   |   |
 2   4   1   5   3       <-- result

当我提交我的解决方案时,它通过了第二个测试用例:。它失败了,可能对其他人来说失败了,但我没有机会在其余情况下测试它。问题是我的代码产生的结果符合任务的假设。[6,5,4,6][3,1][12,6,11,10,5,3,4,6]

当我手动对上述代码的结果进行异运时(,这就是任务中提到的创建编码数组的方式),我能够重新创建编码的数组。decoded[i] xor decoded[i+1]

所以我对这个问题感到困惑。我是运气好还是错过了什么,或者结果不是唯一的?

C++ 算法 排列 解码 异或

评论

0赞 ruakh 11/13/2023
提示:你明白 LeetCode 所说的“第一个正整数的排列”是什么意思吗?如果 LeetCode 说你的答案是错误的,你的答案是否满足该条件?n
0赞 Red.Wave 11/13/2023
提示:您知道所有值;你只需要弄清楚顺序。由于您知道这些值,因此可以将此信息转换为一些与输入混合并解码的可用数据。
0赞 Szyszka947 11/13/2023
@ruakh啊,我明白了。0 不是正数,我的解码数组包含大于 n 的元素。 谢谢。我不知道什么是排列并忽略了它:/
0赞 ruakh 11/13/2023
@Szyszka947:不客气!
1赞 Serge Ballesta 11/13/2023
小心。编码数组中所有元素的异或是...原始元素的第一个和最后一个元素的 XOR!因此,当您使用编码数组的偶数元素的异数进行异数运算时,您将得到奇数元素的异数,而绝对不是原始数组的第一个元素。

答:

1赞 Matt Timmermans 11/14/2023 #1

您需要找到丢失的第一个数字。

在从 1 到 n 的所有数字中,有多少位设置了 0?

假设您假设缺失的数字为 0,对其余数字进行解码,并发现有一个结果设置了位 0,而 b 结果未设置位 0。

如果改为设置假定的第一个数字的位 0,则将有 b 个结果,其中位为 0 且未设置位 0。

由于 a+b = n,而 n 是奇数,我们知道 a != b,因此将缺少的第一个数字的位 0 设置为产生正确计数的任何值。

对剩余的位执行相同的操作,您就拥有了完整的第一个数字,并且可以轻松解码其余部分。