LeetCode 1720 解码异或后的数组 & 1734 解码异或后的序列 题解

LeetCode 1720 解码异或后的数组 & 1734 解码异或后的序列 题解

1720 解码异或后的数组

未知 整数数组 arr 由 n 个非负整数组成。
经编码后变为长度为 n - 1 的另一个整数数组 encoded ,其中 encoded[i] = arr[i] XOR arr[i + 1] 。例如,arr = [1,0,2,1] 经编码后得到 encoded = [1,2,3] 。
给你编码后的数组 encoded 和原数组 arr 的第一个元素 first(arr[0])。
请解码返回原数组 arr 。可以证明答案存在并且是唯一的。
示例 1:
输入:encoded = [1,2,3], first = 1
输出:[1,0,2,1]
解释:若 arr = [1,0,2,1] ,那么 first = 1 且 encoded = [1 XOR 0, 0 XOR 2, 2 XOR 1] = [1,2,3]

在这里插入图片描述
在这里插入图片描述

Go:

func decode(encoded []int, first int) []int {
    if encoded == nil || len(encoded) == 0{
        return nil
    }
    arr := make([]int, len(encoded)+1)
    arr[0] = first
    for i,e := range(encoded){
        arr[i+1] = arr[i] ^ e
    }
    return arr
}

Java:

class Solution {
    public int[] decode(int[] encoded, int first) {
        if(encoded == null || encoded.length == 0){
            return new int[0];
        }
        int n = encoded.length;
        int[] arr = new int[n+1];
        arr[0] = first;
        for(int i = 1; i <= n; i++){
            arr[i] = arr[i-1] ^ encoded[i-1];
        }
        return arr;
    }
}

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]

虽然是不知道arr[0],但是能不能用一些数学技巧,把arr[0]倒逼出来,然后使用第一题的方法求解?
其实配合着本题新加入的一些条件,可以做到。这也是我之前为什么说知道原数组arr的第一个元素arr[0]会是一个解题线索。
我们可以使用A, B, C, D, E代表整数数组perm,注意:它是前 n 个正整数的排列,且 n 是奇数。
为了表达的方便,可以这么定义:将A XOR B(A和B进行异或运算)简写为AB。
思路步骤:

既然我们知道了perm = [A, B, C, D, E],那么encoded = [AB, BC, CD, DE];
根据perm,我们可以得到ABCDE,根据encoded的BC和DE,我们可以得到BCDE;【也就是奇数项的异或】
将ABCDE和BCDE进行异或运算,【就能消去BCDE】得到A,即perm的第一个元素。这时候,
今天的题目转换成上面的第一题。

Java:

class Solution {
    public int[] decode(int[] encoded) {
        if(encoded == null || encoded.length == 0){
            return new int[0];
        }
        int n = encoded.length + 1;
        int all = 0;//0异或任何数字都等于数字本身
        for(int i = 1; i <= n; i++){//整数数组 perm ,是前 n 个正整数的排列
            all ^= i;
        }   
        int odd = 0;
        for(int i = 1; i < n; i += 2){
            odd ^= encoded[i];
        }
        int[] res = new int[n];
        res[0] = all ^ odd;
        for(int i = 1; i < n; i++){
            res[i] = res[i-1] ^ encoded[i-1];
        }
        return res;
    }
}

Go:

func decode(encoded []int) []int {
    n := len(encoded)+1
    total := 0
    for i := 1; i <= n; i++ {
        total ^= i
    }
    odd := 0
    for i := 1; i < n; i += 2 {
        odd ^= encoded[i]
    }
    perm := make([]int, n)
    perm[0] = total ^ odd
    for i, v := range encoded {
        perm[i+1] = perm[i] ^ v
    }
    return perm
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值