题目来源:LeetCode303:区域和检索-数组不可变
问题抽象: 设计一个类 NumArray,用于高效计算整数数组的任意子数组区间和(数组不可变),满足以下核心需求:
-
类功能定义:
- 构造函数:接收整数数组
nums并初始化内部数据结构(数组不可变); - 查询方法:
sumRange(int left, int right)返回子数组[left, right]的元素和(包含两端索引)。
- 构造函数:接收整数数组
-
效率约束:
- 预处理优化:构造函数时间复杂度 O(n)(
n为数组长度); - 查询高效:
sumRange方法时间复杂度 O(1)(避免每次遍历子数组); - 空间复杂度 O(n):允许额外存储线性空间的数据结构。
- 预处理优化:构造函数时间复杂度 O(n)(
-
输入与输出:
- 输入数组
nums:长度1 ≤ n ≤ 10^4,元素值-10^5 ≤ nums[i] ≤ 10^5; - 查询参数
left,right:满足0 ≤ left ≤ right < n; - 输出:区间和(整数)。
- 输入数组
-
边界处理:
- 单元素数组:
sumRange(0,0)返回nums[0]; - 全数组查询:
sumRange(0, n-1)返回数组总和; - 负数和处理:如
nums=[-2,0,3],sumRange(0,2)返回1; - 大数累加:区间和可能超出
2^{31}(但题目保证结果在int范围内)。
- 单元素数组:
类接口定义:
class NumArray {
public NumArray(int[] nums); // 初始化
public int sumRange(int left, int right); // 区间和查询
}
应用场景:频繁查询固定数组的任意子数组和(如金融数据统计、实时分析系统)。
解题思路
- 核心问题:高效处理多次区间求和查询。
- 暴力法的缺陷:每次查询遍历区间,时间复杂度为 O(n),总查询时间达 O(n²),无法满足高频调用。
- 前缀和优化:
- 预处理:在初始化时构建前缀和数组
prefixSum,其中prefixSum[i]存储nums[0]到nums[i-1]的累加和。 - 查询公式:区间
[left, right]的和 =prefixSum[right + 1] - prefixSum[left]。
- 预处理:在初始化时构建前缀和数组
- 复杂度分析:
- 初始化:O(n),遍历一次数组计算前缀和。
- 查询:O(1),直接通过数组下标访问。
- 空间:O(n),存储前缀和数组。
代码实现(Java版)🔥点击下载源码
class NumArray {
private int[] prefixSum; // 前缀和数组
public NumArray(int[] nums) {
int n = nums.length;
prefixSum = new int[n + 1]; // 长度 n+1,prefixSum[0]=0
for (int i = 0; i < n; i++) {
prefixSum[i + 1] = prefixSum[i] + nums[i]; // 递推计算前缀和
}
}
public int sumRange(int left, int right) {
return prefixSum[right + 1] - prefixSum[left]; // 直接通过前缀和计算区间和
}
}
代码说明
- 初始化:
- 创建长度
n+1的prefixSum数组,prefixSum[0] = 0。 - 遍历
nums,递推计算前缀和:prefixSum[i + 1] = prefixSum[i] + nums[i]。
- 创建长度
- 查询:
- 区间
[left, right]的和 =prefixSum[right + 1] - prefixSum[left]。 - 例如:查询
[0, 2]时,prefixSum[3] - prefixSum[0] = 1 - 0 = 1。
- 区间
- 优势:
- 初始化后每次查询仅需 一次减法操作,时间复杂度 O(1)。
- 空间占用仅比原数组多一个单位,空间效率最优。
提交详情(执行用时、内存消耗)

158

被折叠的 条评论
为什么被折叠?



