leetcode
leetcode 2101 ~ 2150
找出前缀异或的原始数组

找出前缀异或的原始数组

难度:

标签:

题目描述

代码结果

运行时间: 56 ms, 内存: 32.5 MB


/*
 * 思路:
 * 使用Java Stream API实现相同的逻辑。
 * 通过流的方式生成arr数组。
 */

import java.util.stream.IntStream;

public class Solution {
    public int[] findArray(int[] pref) {
        return IntStream.range(0, pref.length)
                        .map(i -> i == 0 ? pref[0] : pref[i] ^ pref[i - 1])
                        .toArray();
    }
}

解释

方法:

题解的核心思路是通过利用已知的前缀异或数组 pref 来还原原始数组 arr。首先,arr[0] 直接等于 pref[0]。接着,由于 pref[i] 表示从 arr[0] 到 arr[i] 的异或结果,可以得出 arr[i] = pref[i-1] ^ pref[i],即当前元素与前一个元素的前缀异或。这是基于异或运算的性质:如果 a ^ b = c,则 c ^ b = a。因此,通过遍历 pref 数组,使用每两个相邻元素进行异或运算,即可逐步还原出原始数组 arr。

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
在解题思路中提到`arr[i] = pref[i-1] ^ pref[i]`,但是这个公式如何适用于i=0的情况?
对于i=0的情况,公式`arr[i] = pref[i-1] ^ pref[i]`并不适用,因为当i=0时,不存在pref[i-1]。因此,对于i=0的情况,arr[0]直接等于pref[0]。这是一个特殊情况,需要单独处理。
🦆
对于示例中的解释,怎么通过`pref[i-1] ^ pref[i]`得到初值`arr[0]`?
解释中提到的公式`pref[i-1] ^ pref[i]`并不是用来得到`arr[0]`的。在算法实现中,`arr[0]`是直接从`pref[0]`得到的,即`arr[0] = pref[0]`。之后的数组元素,从`arr[1]`开始,才使用`pref[i-1] ^ pref[i]`来计算。
🦆
题解中使用了`pairwise`函数来遍历`pref`数组的相邻元素,这个函数是标准Python库中的函数吗?如果不是,应该如何实现它?
`pairwise`函数不是Python标准库中的函数。它可以通过使用`itertools`模块中的`pairwise`函数实现(Python 3.10及以上版本支持)。对于低版本的Python,可以手动实现一个类似的功能,例如使用列表推导和zip函数:`[x^y for x, y in zip(pref, pref[1:])]`。
🦆
解题思路中提到异或运算的性质`如果a ^ b = c,则c ^ b = a`,能否进一步解释这一性质是如何应用于本题中的?
异或运算具有可逆的特性。在这个题目中,已知`pref[i]`是从`arr[0]`到`arr[i]`的连续元素的异或结果。因此,`pref[i] = arr[0] ^ arr[1] ^ ... ^ arr[i]`。如果我们知道`pref[i-1] = arr[0] ^ arr[1] ^ ... ^ arr[i-1]`,那么根据异或运算的性质,`pref[i-1] ^ pref[i]`的结果将会是`(arr[0] ^ ... ^ arr[i-1]) ^ (arr[0] ^ ... ^ arr[i-1] ^ arr[i])`。由于异或运算是自己与自己异或结果为0,非自身异或保持不变,所以这将简化为`arr[i]`。这样就利用了异或的性质,从已知的前缀异或结果中恢复出原数组的每个元素。

相关问题