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
}