当前位置: 首页 > news >正文

前缀和题目:子数组异或查询

文章目录

  • 题目
    • 标题和出处
    • 难度
    • 题目描述
      • 要求
      • 示例
      • 数据范围
  • 解法
    • 思路和算法
    • 代码
    • 复杂度分析

题目

标题和出处

标题:子数组异或查询

出处:1310. 子数组异或查询

难度

4 级

题目描述

要求

给定一个正整数数组 arr \texttt{arr} arr,以及一个查询数组 queries \texttt{queries} queries,其中 queries[i] = [left i , right i ] \texttt{queries[i] = [left}_\texttt{i}\texttt{, right}_\texttt{i}\texttt{]} queries[i] = [lefti, righti]

对于每个查询 i \texttt{i} i,计算从 left i \texttt{left}_\texttt{i} lefti right i \texttt{right}_\texttt{i} righti 的异或值(即 arr[left i ] ⊕ arr[left i + 1] ⊕ … ⊕ arr[right i ] \texttt{arr[left}_\texttt{i}\texttt{]} \oplus \texttt{arr[left}_\texttt{i}\texttt{ + 1]} \oplus \ldots \oplus \texttt{arr[right}_\texttt{i}\texttt{]} arr[lefti]arr[lefti + 1]arr[righti])作为查询的结果。

返回一个数组 answer \texttt{answer} answer,其中 answer[i] \texttt{answer[i]} answer[i] 是第 i \texttt{i} i 个查询的结果。

示例

示例 1:

输入: arr = [1,3,4,8], queries = [[0,1],[1,2],[0,3],[3,3]] \texttt{arr = [1,3,4,8], queries = [[0,1],[1,2],[0,3],[3,3]]} arr = [1,3,4,8], queries = [[0,1],[1,2],[0,3],[3,3]]
输出: [2,7,14,8] \texttt{[2,7,14,8]} [2,7,14,8]
解释:
数组中元素的二进制表示形式是:
1 = 0001 \texttt{1} = \texttt{0001} 1=0001
3 = 0011 \texttt{3} = \texttt{0011} 3=0011
4 = 0100 \texttt{4} = \texttt{0100} 4=0100
8 = 1000 \texttt{8} = \texttt{1000} 8=1000
查询的异或值为:
[0,1] = 1 ⊕ 3 = 2 \texttt{[0,1]} = \texttt{1} \oplus \texttt{3} = \texttt{2} [0,1]=13=2
[1,2] = 3 ⊕ 4 = 7 \texttt{[1,2]} = \texttt{3} \oplus \texttt{4} = \texttt{7} [1,2]=34=7
[0,3] = 1 ⊕ 3 ⊕ 4 ⊕ 8 = 14 \texttt{[0,3]} = \texttt{1} \oplus \texttt{3} \oplus \texttt{4} \oplus \texttt{8} = \texttt{14} [0,3]=1348=14
[3,3] = 8 \texttt{[3,3]} = \texttt{8} [3,3]=8

示例 2:

输入: arr = [4,8,2,10], queries = [[2,3],[1,3],[0,0],[0,3]] \texttt{arr = [4,8,2,10], queries = [[2,3],[1,3],[0,0],[0,3]]} arr = [4,8,2,10], queries = [[2,3],[1,3],[0,0],[0,3]]
输出: [8,0,4,4] \texttt{[8,0,4,4]} [8,0,4,4]

数据范围

  • 1 ≤ arr.length ≤ 3 × 10 4 \texttt{1} \le \texttt{arr.length} \le \texttt{3} \times \texttt{10}^\texttt{4} 1arr.length3×104
  • 1 ≤ arr[i] ≤ 10 9 \texttt{1} \le \texttt{arr[i]} \le \texttt{10}^\texttt{9} 1arr[i]109
  • 1 ≤ queries.length ≤ 3 × 10 4 \texttt{1} \le \texttt{queries.length} \le \texttt{3} \times \texttt{10}^\texttt{4} 1queries.length3×104
  • queries[i].length = 2 \texttt{queries[i].length} = \texttt{2} queries[i].length=2
  • 0 ≤ left i ≤ right i < arr.length \texttt{0} \le \texttt{left}_\texttt{i} \le \texttt{right}_\texttt{i} < \texttt{arr.length} 0leftirighti<arr.length

解法

思路和算法

这道题要求对于每个查询计算子数组的元素按位异或。由于数组 arr \textit{arr} arr 的长度以及查询的个数最大为 3 × 10 4 3 \times 10^4 3×104,因此计算子数组的元素按位异或时,不能使用遍历子数组的做法,而是需要使用时间复杂度更低的做法。可以使用前缀和的思想实现。

首先计算数组 arr \textit{arr} arr 的前缀异或数组。创建前缀异或数组 prefixXors \textit{prefixXors} prefixXors,其长度为 arr \textit{arr} arr 的长度加 1 1 1 prefixXors [ i ] \textit{prefixXors}[i] prefixXors[i] 表示 arr \textit{arr} arr 的长度为 i i i 的前缀异或,即下标范围 [ 0 , i − 1 ] [0, i - 1] [0,i1] 中的 i i i 个元素的按位异或。

根据按位异或的性质, prefixXors [ i + 1 ] ⊕ prefixXors [ i ] = arr [ i ] \textit{prefixXors}[i + 1] \oplus \textit{prefixXors}[i] = \textit{arr}[i] prefixXors[i+1]prefixXors[i]=arr[i] prefixXors [ i + 1 ] = prefixXors [ i ] ⊕ arr [ i ] \textit{prefixXors}[i + 1] = \textit{prefixXors}[i] \oplus \textit{arr}[i] prefixXors[i+1]=prefixXors[i]arr[i],由此可以遍历数组 arr \textit{arr} arr 一次计算得到前缀异或数组。

得到前缀异或数组 prefixXors \textit{prefixXors} prefixXors 之后,对于 queries [ i ] = [ left i , right i ] \textit{queries}[i] = [\textit{left}_i, \textit{right}_i] queries[i]=[lefti,righti],查询结果可以通过前缀异或数组得到:

answer [ i ] = prefixXors [ right i + 1 ] ⊕ prefixXors [ left i ] \textit{answer}[i] = \textit{prefixXors}[\textit{right}_i + 1] \oplus \textit{prefixXors}[\textit{left}_i] answer[i]=prefixXors[righti+1]prefixXors[lefti]

代码

class Solution {public int[] xorQueries(int[] arr, int[][] queries) {int length = arr.length;int[] prefixXors = new int[length + 1];for (int i = 0; i < length; i++) {prefixXors[i + 1] = prefixXors[i] ^ arr[i];}int queriesCount = queries.length;int[] answer = new int[queriesCount];for (int i = 0; i < queriesCount; i++) {int left = queries[i][0], right = queries[i][1];answer[i] = prefixXors[right + 1] ^ prefixXors[left];}return answer;}
}

复杂度分析

  • 时间复杂度: O ( n + q ) O(n + q) O(n+q),其中 n n n 是数组 arr \textit{arr} arr 的长度, q q q 是数组 queries \textit{queries} queries 的长度。需要遍历数组 arr \textit{arr} arr 一次计算前缀异或数组,需要遍历数组 queries \textit{queries} queries 一次计算每个查询的结果,每个查询的计算时间是 O ( 1 ) O(1) O(1),因此时间复杂度是 O ( n + q ) O(n + q) O(n+q)

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组 arr \textit{arr} arr 的长度。需要创建长度为 n + 1 n + 1 n+1 的前缀异或数组。

相关文章:

  • react实现axios 的简单封装
  • 解决新版RN 热更新报错:recreateReactContextInBackground
  • 基于sample_aiisp例子,创建3路编码流,记录
  • 【微软RDP协议】微软RDP协议技术架构特点与跨地域应用实践
  • 【 java 虚拟机知识 第二篇 】
  • android 之 CALL
  • 使用adb 抓取perfetto-trace的注意事项
  • 基于 Redis 的幂等性设计:SpringBoot @Async 在高并发 MySQL 日志存储中的应用
  • Mac 系统 Node.js 安装与版本管理指南
  • RAG检索前处理
  • GO后端开发内存管理及参考答案
  • adb 查看android 设备的硬盘及存储空间
  • 录制mp4 rospy
  • 2025年中国人工智能发展研究报告:技术突破、行业变革与全球竞争新格局
  • Spring 路由匹配机制详解:时间复杂度从 O(n) 降至 O(log n)
  • 学习STC51单片机36(芯片为STC89C52RCRC)智能小车3(PWM差速小车)
  • Redis 安装实践:基于鲲鹏 ARM 架构 Ubuntu 环境
  • 随记:sw2urdf插件导出urdf模型在ROS2-rviz2显示
  • 电流传感器在工业自动化中的应用
  • Tess4J:基于 Java 的 OCR 解决方案
  • 兖州中材建设有限公司网站/营销型网站建设解决方案
  • 网站开发用什么技术asp/seo搜索优化招聘
  • 汕头网站seo外包/百度的企业网站
  • 做的新网站网上搜不到/互联网营销工具
  • 做网站让用seo刷新是哪个键/重庆网站推广
  • 室内设计师讲解方案话术/优化关键词推广