leetcode-1734-解码异或后的排列

描述

img

异或及计算方法

  • 概念

    异或Exclusive OR,缩写XOR。数学符号:\bigoplus, 在键盘上表示:^ 符号

    异或的运算方式为 相同为0,不同为1

  • 其他运算法则

    1. a ^ a = 0
    2. a ^ 0 = a
    3. a ^ b = b ^ a
    4. a ^ b ^ c = a ^ (b ^ c) = &a ^ b) ^ c
    5. a ^ b ^ a = b
    6. a ^ b = c ====> a ^ c = b

思路

  1. perm数组长度比encode数组长度大1

  2. perm数组长度n,内容为前n个正整数的排列(有可能是打乱顺序的)

  3. // 假设数组perm = [a, b, c, d, e] encode = [h, i, j, k]
    h = a ^ b;			----------1式
    i = b ^ c;			----------2式
    j = c ^ d;			----------3式
    k = d ^ e;			----------4式
    // 令 x = a ^ b ^ c ^ d ^ e, y = b ^ c ^ d ^ e, 则a = x ^ y;
    // 然后 b = a ^ (a ^ b), a ^ b 即为encode数组的第一个数h
    // c = b ^ (b ^ c), b ^ c 即为encode数组的第二个数i
    // ...
    
  4. 如何得到x与y?

    • x:

      长度容易求得:encode数组长度+1,然后一次异或即可得到

      且 1 ^ 2 ^ 3 ^ 4 ^ 5 = 2 ^ 4 ^ 5 ^ 1 ^3,顺序打乱,结果一样

    • y:

      以上述代码框为例 y = b ^ c ^ d ^ e = 1式 ^ 3式 = i ^ k

      间隔为1,依次异或可得到

代码

class Solution{
    public int[] decode(int[] encoded){
        int len = encoded.length + 1;
        int[] decode = new int[len];
        int x = 0, y = 0;
        // 获得x
        for(int i = 1; i <= len; i++){
            x = x ^ i;
        }
        // 获得y
        for(int j = 1; j < encoded.length; j+=2){
            y = y ^ encoded[j];
        }
        int firstNum = x ^ y;
        decode[0] = firstNum;
        // 根据第一个数,依次计算出其他的数
        for(int k = 1; k < len; k++){
            decode[k] = decode[k - 1] ^ encoded[k - 1];
        }
        return decode;
    }
}
posted on 2021-05-12 20:17  caoshikui  阅读(70)  评论(0)    收藏  举报