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

前缀和实现题目:区域和检索 - 数组不可变

文章目录

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

题目

标题和出处

标题:区域和检索 - 数组不可变

出处:303. 区域和检索 - 数组不可变

难度

3 级

题目描述

要求

给定一个整数数组 nums \texttt{nums} nums,处理以下类型的多个查询:

  • 计算下标 left \texttt{left} left right \texttt{right} right 之间的 nums \texttt{nums} nums 元素的(包含 left \texttt{left} left right \texttt{right} right),其中 left ≤ right \texttt{left} \le \texttt{right} leftright

实现 NumArray \texttt{NumArray} NumArray 类:

  • NumArray(int[] nums) \texttt{NumArray(int[] nums)} NumArray(int[] nums) 使用数组 nums \texttt{nums} nums 初始化对象。
  • int sumRange(int left, int right) \texttt{int sumRange(int left, int right)} int sumRange(int left, int right) 返回数组 nums \texttt{nums} nums 中的下标 left \texttt{left} left right \texttt{right} right 之间的元素的,包含 left \texttt{left} left right \texttt{right} right(即 nums[left] + nums[left + 1] + ... + nums[right] \texttt{nums[left] + nums[left + 1] + ... + nums[right]} nums[left] + nums[left + 1] + ... + nums[right])。

示例

示例 1:

输入:
["NumArray", "sumRange", "sumRange", "sumRange"] \texttt{["NumArray", "sumRange", "sumRange", "sumRange"]} ["NumArray", "sumRange", "sumRange", "sumRange"]
[[[-2, 0, 3, -5, 2, -1]], [0, 2], [2, 5], [0, 5]] \texttt{[[[-2, 0, 3, -5, 2, -1]], [0, 2], [2, 5], [0, 5]]} [[[-2, 0, 3, -5, 2, -1]], [0, 2], [2, 5], [0, 5]]
输出:
[null, 1, -1, -3] \texttt{[null, 1, -1, -3]} [null, 1, -1, -3]
解释:
NumArray numArray = new NumArray([-2, 0, 3, -5, 2, -1]); \texttt{NumArray numArray = new NumArray([-2, 0, 3, -5, 2, -1]);} NumArray numArray = new NumArray([-2, 0, 3, -5, 2, -1]);
numArray.sumRange(0, 2); \texttt{numArray.sumRange(0, 2);} numArray.sumRange(0, 2); // 返回 (-2) + 0 + 3 = 1 \texttt{(-2) + 0 + 3 = 1} (-2) + 0 + 3 = 1
numArray.sumRange(2, 5); \texttt{numArray.sumRange(2, 5);} numArray.sumRange(2, 5); // 返回 3 + (-5) + 2 + (-1) = -1 \texttt{3 + (-5) + 2 + (-1) = -1} 3 + (-5) + 2 + (-1) = -1
numArray.sumRange(0, 5); \texttt{numArray.sumRange(0, 5);} numArray.sumRange(0, 5); // 返回 (-2) + 0 + 3 + (-5) + 2 + (-1) = -3 \texttt{(-2) + 0 + 3 + (-5) + 2 + (-1) = -3} (-2) + 0 + 3 + (-5) + 2 + (-1) = -3

数据范围

  • 1 ≤ nums.length ≤ 10 4 \texttt{1} \le \texttt{nums.length} \le \texttt{10}^\texttt{4} 1nums.length104
  • -10 5 ≤ nums[i] ≤ 10 5 \texttt{-10}^\texttt{5} \le \texttt{nums[i]} \le \texttt{10}^\texttt{5} -105nums[i]105
  • 0 ≤ left ≤ right < nums.length \texttt{0} \le \texttt{left} \le \texttt{right} < \texttt{nums.length} 0leftright<nums.length
  • 最多调用 10 4 \texttt{10}^\texttt{4} 104 sumRange \texttt{sumRange} sumRange

解法

思路和算法

这道题是一维前缀和的实现与应用。计算数组 nums \textit{nums} nums 中的任意子数组的元素和,方法是首先计算数组 nums \textit{nums} nums 的前缀和数组,然后根据前缀和数组在 O ( 1 ) O(1) O(1) 的时间内计算任意子数组的元素和。

n n n 表示数组 nums \textit{nums} nums 的长度,创建长度为 n + 1 n + 1 n+1 的前缀和数组 prefixSums \textit{prefixSums} prefixSums,对于 0 ≤ i ≤ n 0 \le i \le n 0in prefixSums [ i ] \textit{prefixSums}[i] prefixSums[i] 表示 nums \textit{nums} nums 的长度为 i i i 的前缀和,即下标范围 [ 0 , i − 1 ] [0, i - 1] [0,i1] 中的 i i i 个元素之和:

prefixSums [ i ] = ∑ k = 0 i − 1 nums [ k ] \textit{prefixSums}[i] = \sum\limits_{k = 0}^{i - 1} \textit{nums}[k] prefixSums[i]=k=0i1nums[k]

特别地, prefixSums [ 0 ] = 0 \textit{prefixSums}[0] = 0 prefixSums[0]=0

对于 0 ≤ i < n 0 \le i < n 0i<n,考虑 prefixSums [ i + 1 ] \textit{prefixSums}[i + 1] prefixSums[i+1] prefixSums [ i ] \textit{prefixSums}[i] prefixSums[i] 之差:

prefixSums [ i + 1 ] − prefixSums [ i ] = ∑ k = 0 i nums [ k ] − ∑ k = 0 i − 1 nums [ k ] = ∑ k = 0 i − 1 nums [ k ] + nums [ i ] − ∑ k = 0 i − 1 nums [ k ] = nums [ i ] \begin{aligned} &\textit{prefixSums}[i + 1] - \textit{prefixSums}[i] \\ = &\sum\limits_{k = 0}^{i} \textit{nums}[k] - \sum\limits_{k = 0}^{i - 1} \textit{nums}[k] \\ = &\sum\limits_{k = 0}^{i - 1} \textit{nums}[k] + \textit{nums}[i] - \sum\limits_{k = 0}^{i - 1} \textit{nums}[k] \\ = &\textit{nums}[i] \end{aligned} ===prefixSums[i+1]prefixSums[i]k=0inums[k]k=0i1nums[k]k=0i1nums[k]+nums[i]k=0i1nums[k]nums[i]

因此 prefixSums [ i + 1 ] − prefixSums [ i ] = nums [ i ] \textit{prefixSums}[i + 1] - \textit{prefixSums}[i] = \textit{nums}[i] prefixSums[i+1]prefixSums[i]=nums[i] prefixSums [ i + 1 ] = prefixSums [ i ] + nums [ i ] \textit{prefixSums}[i + 1] = \textit{prefixSums}[i] + \textit{nums}[i] prefixSums[i+1]=prefixSums[i]+nums[i]。当 prefixSums [ i ] \textit{prefixSums}[i] prefixSums[i] 的值已知时,可以使用 O ( 1 ) O(1) O(1) 的时间计算 prefixSums [ i + 1 ] \textit{prefixSums}[i + 1] prefixSums[i+1] 的值,因此可以使用 O ( n ) O(n) O(n) 的时间计算整个前缀和数组。

得到前缀和数组 prefixSums \textit{prefixSums} prefixSums 之后,对于 0 ≤ left ≤ right < n 0 \le \textit{left} \le \textit{right} < n 0leftright<n,下标范围 [ left , right ] [\textit{left}, \textit{right}] [left,right] 的子数组的元素和可以通过前缀和数组得到:

sumRange ( left , right ) = prefixSums [ right + 1 ] − prefixSums [ left ] \textit{sumRange}(\textit{left}, \textit{right}) = \textit{prefixSums}[\textit{right} + 1] - \textit{prefixSums}[\textit{left}] sumRange(left,right)=prefixSums[right+1]prefixSums[left]

代码

class NumArray {int[] prefixSums;public NumArray(int[] nums) {int n = nums.length;prefixSums = new int[n + 1];for (int i = 0; i < n; i++) {prefixSums[i + 1] = prefixSums[i] + nums[i];}}public int sumRange(int left, int right) {return prefixSums[right + 1] - prefixSums[left];}
}

复杂度分析

  • 时间复杂度:构造方法的时间复杂度是 O ( n ) O(n) O(n) sumRange \textit{sumRange} sumRange 操作的时间复杂度是 O ( 1 ) O(1) O(1),其中 n n n 是数组 nums \textit{nums} nums 的长度。构造方法需要创建长度为 n + 1 n + 1 n+1 的前缀和数组并计算每个元素的前缀和,每次 sumRange \textit{sumRange} sumRange 操作计算子数组的元素和的时间是 O ( 1 ) O(1) O(1)

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

http://www.xdnf.cn/news/662977.html

相关文章:

  • 第2章(新)Day2 - Python基础入门
  • 【图论 并集查找】P3671 [USACO17OPEN] Where‘s Bessie? S|普及+
  • python打卡训练营打卡记录day37
  • 自驾总结Module(综述)
  • CN 第二章 应用层-判断题
  • uniapp-商城-70-shop(3-商品列表,点击规格,进行属性选择)
  • AI巡检系统适合多大面积的餐厅?
  • lc hot 100之:找到所有数组中消失的数字
  • SQL:合并查询(UNION)
  • DL00347-基于人工智能YOLOv11的安检X光危险品刀具检测含数据集
  • 报文完整性与数字签名
  • 【修电脑的小记录】打不开某个网站
  • Linux `ls` 命令深度解析与高阶应用指南
  • Mysql数据库之日志与备份
  • 论坛系统自动化测试实战
  • SpringAI--RAG知识库
  • Windows中安装Neo4j图数据库的配置
  • 数据架构:零售业数字化转型的“隐形引擎”
  • 什么是软件验收测试,出验收测试报告的软件检测机构推荐
  • MySQL问题:数据库有哪些存储引擎,它们有什么区别?
  • Jenkins部署
  • 小型电磁脉冲干扰(EMP)的原理及组成
  • L1-111 大幂数 - java
  • day37打卡
  • 二、网络安全常见编码及算法-(1)
  • 爱芯元智芯片推理cn-clip
  • 11.10 LangGraph状态管理实战:Reducers模式如何重塑企业级多节点协作?
  • 云化全场景+AI智算双擎驱动,打造高教数智化转型新范式,麒麟信安闪耀第63届高等教育博览会!
  • Linux基础IO----动态库与静态库
  • MQTT 在云平台与设备通讯中的连接特性与通讯性质深度解析