前端刷题路-Day45:解码异或后的数组(题号1720)

680 阅读1分钟

这是我参与更文挑战的第9天,活动详情查看: 更文挑战

解码异或后的数组(题号1720)

题目

未知 整数数组 arrn 个非负整数组成。

经编码后变为长度为 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]

示例 2:

输入:encoded = [6,2,7,3], first = 4
输出:[4,2,0,7,4]

提示:

  • 2 <= n <= 104
  • encoded.length == n - 1
  • 0 <= encoded[i] <= 105
  • 0 <= first <= 105

链接

leetcode-cn.com/problems/de…

解释

这题啊,这题是小学二年级学过的知识。

异或这个方法其实比较狗,具体就不介绍啦,篇幅较长,有兴趣的可以自行查阅相关资料。

这里只要当前一种计算方法,或者说一个符号即可,类似于加减乘除。

异或方法有如下特点:

  • 异或运算满足交换律和结合律
  • 任意整数和自身做异或运算的结果都等于 0,即 x⊕x=0
  • 任意整数和 0 做异或运算的结果都等于其自身,即 x⊕0=0⊕x=x

这里的就是题目上的XOR——异或运算。

首先看看交换律和结合律,这一点在小学就学过啦,和乘法类似,在等式两边可以随意添加元素,那么此时从正常的异或运算式开始推导,可以得到这样的过程👇:

            encoded[i−1] = arr[i−1] ⊕ arr[i]
encoded[i−1] ⊕ arr[i−1] = arr[i−1] ⊕ arr[i] ⊕ arr[i−1]
arr[i−1] ⊕ encoded[i−1] = arr[i−1] ⊕ arr[i−1] ⊕ arr[i]
arr[i−1] ⊕ encoded[i−1] = 0 ⊕ arr[i]
arr[i−1] ⊕ encoded[i−1] = arr[i]

整个推导过程就是利用👆说到的三个特性,从而得出反向推到出arr[i]的公式,拿到这个公式后就可以反向得出原数组啦~

自己的答案

更好的方法(官方解法)

官方解法就比较简单了👇:

var decode = function(encoded, first) {
    const n = encoded.length + 1;
    const arr = new Array(n).fill(0);
    arr[0] = first;
    for (let i = 1; i < n; i++) {
        arr[i] = arr[i - 1] ^ encoded[i - 1];
    }
    return arr;
};

对吧,就是这么简单,没有多余的操作。

但是性能比较一般,👇介绍笔者觉得比较好的方法。

更好都方法(节省空间)

官方解法其实新建了一个对象来存储反向转化后的数组,这里直接修改原数组,也就是encoded数组,修改完成后直接返回即可。

var decode = function(encoded, first) {
  encoded.unshift(first)
  for (let i = 1; i < encoded.length; i++) {
    encoded[i] = encoded[i - 1] ^ encoded[i]
  }
  return encoded
};

更好的方法(节省时间)

这种方法就和原方法差不多了,稍微优化了一下。

var decode = function(encoded, first) {
  let cur = first
  let result = [first]
  for (let e of encoded) {
    cur = cur ^ e
    result.push(cur)
  }
  return result
};

这两种方法笔者感觉都比官方答案好些,有兴趣的可以点击这里查看原答案。



PS:想查看往期文章和题目可以点击下面的链接:

这里是按照日期分类的👇

前端刷题路-目录(日期分类)

经过有些朋友的提醒,感觉也应该按照题型分类
这里是按照题型分类的👇

前端刷题路-目录(题型分类)

有兴趣的也可以看看我的个人主页👇

Here is RZ