1310. 子数组异或查询

本文介绍了解决LeetCode上子数组XOR查询问题的两种方法:直接计算法和前缀和法,并分析了各自的时间与空间复杂度。
2021-05-12 LeetCode每日一题

链接:https://leetcode-cn.com/problems/xor-queries-of-a-subarray/

题目

有一个正整数数组 arr,现给你一个对应的查询数组 queries,其中 queries[i] = [Li, Ri]。

对于每个查询 i,请你计算从 Li 到 Ri 的 XOR 值(即 arr[Li] xor arr[Li+1] xor … xor arr[Ri])作为本次查询的结果。

并返回一个包含给定查询 queries 所有结果的数组。

输入:arr = [1,3,4,8], queries = [[0,1],[1,2],[0,3],[3,3]]
输出:[2,7,14,8] 
解释:
数组中元素的二进制表示形式是:
1 = 0001 
3 = 0011 
4 = 0100 
8 = 1000 
查询的 XOR 值为:
[0,1] = 1 xor 3 = 2 
[1,2] = 3 xor 4 = 7 
[0,3] = 1 xor 3 xor 4 xor 8 = 14 
[3,3] = 8

输入:arr = [4,8,2,10], queries = [[2,3],[1,3],[0,0],[0,3]]
输出:[8,0,4,4]
    
1 <= arr.length <= 3 * 10^4
1 <= arr[i] <= 10^9
1 <= queries.length <= 3 * 10^4
queries[i].length == 2
0 <= queries[i][0] <= queries[i][1] < arr.length

分析

没啥好说的,直接写吧。

class Solution {
    public int[] xorQueries(int[] arr, int[][] queries) {
        int len = queries.length;
        int[] res = new int[len];

        for (int i = 0; i < len; i++) {
            int a = queries[i][1];
            int b = queries[i][0];
            while (a >= b) {
                res[i] ^= arr[a--];
            }
        }

        return res;
    }
}

时间复杂度O(m * n),空间复杂度O(n)。

在这里插入图片描述
emmm…感觉分分钟就要超时了。

本题还可以使用前缀和来求解。**利用异或运算中的「相同数值进行运算结果为 0」的特性。**对于数组,要求[a , b]区间的异或结果,可以通过[0, a - 1]和[0, b]的异或求得。

class Solution {
    public int[] xorQueries(int[] arr, int[][] queries) {
        int len = queries.length, n = arr.length;
        int[] res = new int[len];
        int[] sum = new int[n + 1];

        for (int i = 1; i <= n; i++) {
            sum[i] = sum[i - 1] ^ arr[i - 1];
        }

        for (int i = 0; i < len; i++) {
            int a = queries[i][1];
            int b = queries[i][0];
            res[i] = sum[a + 1] ^ sum[b]; 
        }

        return res;
    }
}

在这里插入图片描述
时间复杂度:令 arr 数组长度为 n,queries数组的长度为 m。预处理前缀和数组复杂度为 O(n);查询的复杂度为 O(m)。整体复杂度为 O(n + m)

空间复杂度:O(n)

<think>好的,用户想了解数组异或操作的实现和应用场景。首先,我需要回忆一下异或操作的基本特性,因为这是理解其应用的基础。记得异或操作符是位运算的一种,符号通常是^,特性是相同为0,不同为1。还有几个重要性质,比如交换律、结合律,以及a ^ a = 0和a ^ 0 = a。这些特性在数组操作中特别有用。 然后,用户提到了数组异或操作,可能是指对数组中的元素进行异或运算,或者利用异或来解决数组相关的问题。常见的应用场景之一是找出数组中唯一出现一次的数字,其他数字都出现两次。这种情况下,异或可以高效解决,因为成对的数字异或后会抵消为0,剩下的就是那个单独的数字。这个例子在引用[1]中也有提到,需要引用一下。 接下来,实现方面可能需要考虑不同的编程语言,比如C、Python或者使用numpy库。例如,在C语言中,可以直接用循环遍历数组,逐个异或;而在Python中,可以用reduce函数来累积异或结果。另外,numpy.bitwise_xor函数可以处理数组的按位异或操作,这在引用[2]中有示例,应该提到这一点。 另一个应用场景是子数组异或查询的问题,比如LeetCode的题目1310,引用[3]中提到了使用前缀异或数组来高效处理多个查询。需要解释前缀异或的概念,以及如何通过预处理数组来快速得到任意子数组异或结果。这涉及到前缀和的思想,但应用于异或运算。 此外,可能还有一些其他应用,比如数据加密中的简单异或加密,或者交换两个变量的值而不使用临时变量。不过数据加密的例子在引用[2]里已经提到,可以引用一下。交换变量虽然经典,但可能用户更关注数组操作,所以可以简要带过。 在实现部分,需要给出不同语言的代码示例。例如,C语言的循环实现,Python中使用reduce,以及numpy的bitwise_xor用法。同时,对于前缀异或数组,可以给出一个Python的实现示例,并解释其原理。 需要注意的是,用户可能对异或操作的具体实现细节和优化方法感兴趣,比如如何处理大规模数组,或者如何利用异或的特性来简化算法。此外,可能还要提到异或操作的时间复杂度,通常是O(n),因为需要遍历数组一次,空间复杂度可能为O(1)或者O(n)取决于具体应用。 最后,生成相关问题时要围绕实现细节、优化方法、其他应用场景以及不同语言中的处理方式来提问,帮助用户深入理解。同时确保引用正确,每个引用对应到相应的内容,比如引用[1]对应找出单独数字,引用[2]对应numpy和加密,引用[3]对应前缀异或查询。</think>### 数组异或操作的实现与应用场景 #### 一、异或操作的核心特性 异或操作符($\oplus$)的数学定义为: $$a \oplus b = (\neg a \land b) \lor (a \land \neg b)$$ 其核心特性包括: 1. **交换律**:$a \oplus b = b \oplus a$ 2. **结合律**:$(a \oplus b) \oplus c = a \oplus (b \oplus c)$ 3. **自反性**:$a \oplus a = 0$ 4. **恒等性**:$a \oplus 0 = a$ 这些特性是异或操作在数组处理中广泛应用的基础[^1]。 #### 二、实现方式与代码示例 ##### 1. 基础实现(C语言) ```c int array_xor(int* arr, int size) { int result = 0; for(int i=0; i<size; i++){ result ^= arr[i]; } return result; } ``` 时间复杂度为$O(n)$,空间复杂度$O(1)$。 ##### 2. Python高阶实现 ```python from functools import reduce arr = [3, 1, 2, 1, 2] result = reduce(lambda x,y: x^y, arr) ``` ##### 3. 使用numpy库 ```python import numpy as np arr = np.array([5, 3, 5]) result = np.bitwise_xor.reduce(arr) # 输出3[^2] ``` #### 三、典型应用场景 1. **唯一数字检测** 在数组$[4,1,2,1,2]$中,所有元素异或后结果为$4$,可快速找出唯一出现一次的数字[^1]。 2. **子数组异或查询优化** 通过构建前缀异或数组: $$prefix[i+1] = prefix[i] \oplus arr[i]$$ 查询区间$[L,R]$的异或值可优化为: $$prefix[L] \oplus prefix[R+1]$$ 该方案将多次查询的时间复杂度从$O(nq)$优化到$O(n+q)$[^3]。 3. **数据加密** 通过密钥与数据的按位异或实现简单加密: ```python data = np.array([0b1100, 0b1010]) key = 0b1111 encrypted = np.bitwise_xor(data, key) # 加密 decrypted = np.bitwise_xor(encrypted, key) # 解密[^2] ``` #### 四、进阶应用 1. **数组去重检测** 结合哈希表可检测重复模式 2. **图像处理** 在OpenCV中用于图像混合 3. **网络协议** 校验和计算
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值