LeetCode 1734. 解码异或后的排列

1734. 解码异或后的排列

题目描述:

给你一个整数数组 perm ,它是前 n 个正整数的排列,且 n 是个 奇数

它被加密成另一个长度为 n - 1 的整数数组 encoded ,满足 encoded[i] = perm[i] XOR perm[i + 1] 。比方说,如果 perm = [1,3,2] ,那么 encoded = [2,1]

给你 encoded 数组,请你返回原始数组 perm 。题目保证答案存在且唯一。

示例 1:

输入:encoded = [3,1]
输出:[1,2,3]
解释:如果 perm = [1,2,3] ,那么 encoded = [1 XOR 2,2 XOR 3] = [3,1]

示例 2:

输入:encoded = [6,5,4,6]
输出:[2,4,1,5,3]

提示:

  • 3 <= n < 105
  • n 是奇数。
  • encoded.length == n - 1

思考:

这个题首先需要具备以下几个知识点:

  • 0和任何自然数异或得到的结果都是对方自己,公式 0 ⨁ x = x ( x ! = 0 ) 0 \bigoplus x = x(x != 0) 0x=x(x!=0)
  • 若存在 a ⨁ b = c a \bigoplus b = c ab=c,则 a = b ⨁ c a = b \bigoplus c a=bc
  • 题目中描述了 n n n为奇数,那么 n − 1 n-1 n1为偶数

根据题意,数组perm的所有元素是自然数 [ 1 , n ] [1,n] [1,n],那么将 1 ⨁ 2 ⨁ 3 ⨁ . . . ⨁ n 1\bigoplus 2 \bigoplus3 \bigoplus ...\bigoplus n 123...n得到的结果 r e s res res就是perm数组所有元素异或的结果。

然后我们画图可以看出

e n c o d e d [ 1 ] = p e r m [ 1 ] ⨁ p e r m [ 2 ] encoded[1] = perm[1] \bigoplus perm[2] encoded[1]=perm[1]perm[2]

e n c o d e d [ 3 ] = p e r m [ 3 ] ⨁ p e r m [ 4 ] encoded[3] = perm[3] \bigoplus perm[4] encoded[3]=perm[3]perm[4]

e n c o d e d [ 5 ] = p e r m [ 5 ] ⨁ p e r m [ 6 ] encoded[5] = perm[5] \bigoplus perm[6] encoded[5]=perm[5]perm[6]

e n c o d e d [ 7 ] = p e r m [ 7 ] ⨁ p e r m [ 8 ] encoded[7] = perm[7] \bigoplus perm[8] encoded[7]=perm[7]perm[8]

观察规律我们可以发现,下标从1开始,每次递增2,将所有这样的 e n c o d e d [ i ] encoded[i] encoded[i]异或得到的结果 a n s ans ans就是 p r e m prem prem数组从下标1开始一直到下标 n − 1 n-1 n1结束的所有元素异或结果。即

e n c o d e d [ 1 ] ⨁ e n c o d e d [ 3 ] ⨁ e n c o d e d [ 5 ] ⨁ . . . ⨁ e n c o d e d [ n − 2 ] = p e r m [ 1 ] ⨁ p e r m [ 2 ] ⨁ p e r m [ 3 ] ⨁ . . . ⨁ p e r m [ n − 1 ] encoded[1] \bigoplus encoded[3] \bigoplus encoded[5] \bigoplus ... \bigoplus encoded[n-2] = perm[1] \bigoplus perm[2] \bigoplus perm[3] \bigoplus ... \bigoplus perm[n-1] encoded[1]encoded[3]encoded[5]...encoded[n2]=perm[1]perm[2]perm[3]...perm[n1]

由于题目中提到n是奇数,因此上式的左边的元素个数一定为偶数个

这样,我们将 r e s ⨁ a n s res \bigoplus ans resans进行计算得到的结果就是 p r e m [ 0 ] prem[0] prem[0]

再利用我上述提到的第二个知识点“若存在 a ⨁ b = c a \bigoplus b = c ab=c,则 a = b ⨁ c a = b \bigoplus c a=bc”,由 e n c o d e d [ i ] = p r e m [ i ] ⨁ p e r m [ i + 1 ] encoded[i] = prem[i] \bigoplus perm[i+1] encoded[i]=prem[i]perm[i+1]可以得到 p e r m [ i + 1 ] = p e r m [ i ] ⨁ e n c o d e d [ i ] perm[i+1] = perm[i] \bigoplus encoded[i] perm[i+1]=perm[i]encoded[i]

好了,到此此题思路讲述完毕。代码如下展示

class Solution {
    
    
    public int[] decode(int[] encoded) {
    
    
        int res = 0;
        int ans = 0;
        // 实际上perm 的长度要比encoded的长度要多1
        int n = encoded.length;
        // 这个n + 1计算后得到的n对应题目中描述的n
        n = n + 1;
        for (int i = 1; i <= n ; i++) {
    
    
            res ^= i;
        }
        for (int i = 1; i <= n - 1; i += 2) {
    
    
            ans ^= encoded[i];
        }
        int[] arr = new int[n];
        arr[0] = res ^ ans;
        for (int i = 1; i < n; i++) {
    
    
            arr[i] = encoded[i-1] ^ arr[i-1];
        }
        return arr;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_41688840/article/details/116642337