1734. 解码异或后的排列

248 阅读2分钟

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

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]

解题思路

这道题规定了数组perm 是前 n 个正整数的排列,其中 n 是奇数,所以我们需要把充分利用给到的这个条件,才能进行推导。

设x=1 ^ 2 ^ 3 ^ ...^n 那么perm[0]=x ^ encoded[1] ^ encoded[3]... 因为encoded[i] = perm[i] XOR perm[i + 1],所以perm[i + 1]=encoded[i] XOR perm[i] 若知道了perm[0]自然可以推出perm[1],如此类推,就可以推出所有

推导

为什么可知perm[0]=x ^ encoded[1] ^ encoded[3]...? 因为encoded[1] = perm[1] XOR perm[2] ,encoded[3] = perm[3] XOR perm[4]... 因此可得encoded[1] ^ encoded[3]...= perm[1]^ perm[2]^ perm[3]^ perm[4]...

又因为perm是前 n 个正整数的排列,所以 perm[0]^perm[1]^ perm[2]^ perm[3]^ perm[4]...=1 ^ 2 ^ 3 ^ ...^n=x

因此可得perm[0]=x ^ encoded[1] ^ encoded[3]...

代码

func decode(encoded []int) []int {

	n:=len(encoded)+1
	odd:=0
	for i := 1; i < len(encoded) ; i+=2  {
		odd^=encoded[i]
	}
	all:=0
	for i := 1; i <=n ; i++ {
		all^=i
	}
	pre:=all^odd
	res := make([]int, n)
	res[0]=pre
	for j, code := range encoded {
		cur:=pre^code
		res[j+1]=cur
		pre=cur
	}
	return res
}

时间复杂度:O(n),其中 n 是原始数组 perm 的长度。计算 res 和 odd 各需要遍历长度为 n−1 的数组 encoded 一次,计算原数组 perm 的每个元素值也需要遍历长度为n−1 的数组encoded 一次。

空间复杂度:O(1)。注意空间复杂度不考虑返回值。