区域和检索-数组不可变-LeetCode
303. 区域和检索 - 数组不可变
🎯 问题描述
描述:
给定一个整数数组 nums,处理以下类型的多个查询:
计算索引 left 和 right(包含 left 和 right)之间的 nums 元素的和。
实现 NumArray 类:
NumArray(int[] nums):使用数组nums初始化对象。int sumRange(int left, int right):返回数组nums中索引left和right之间(包含)的元素和。
说明:
-
这是一个前缀和的基础应用题。
-
核心策略:
- 利用数学性质:区间和 等于前缀和 减去前缀和 。
- 公式:。
-
代码特点:
- 当前代码在
sumRange中直接使用了 Python 的切片和内置sum函数。这是一种写法简洁但效率较低的“伪前缀和”实现。
- 当前代码在
-
示例:
-
示例 1:
1 | 输入: |
💻 解题思路
思路1:朴素前缀和(当前代码实现)
核心逻辑
- 存储原数组:
- 在
__init__中保存传入的nums。
- 在
- 利用切片计算:
sum(self.nums[:right+1]):计算从下标 0 到right的累加和。sum(self.nums[:left]):计算从下标 0 到left-1的累加和。- 两者相减即为区间
[left, right]的和。
代码实现
1 | class NumArray: |
📊 性能分析
- 时间复杂度:
__init__: 。sumRange: 。- 因为每次调用
sum和切片操作都需要遍历数组的一部分。如果有 次查询,总时间复杂度为 。 - 注:这在查询次数较多时效率较低。
- 因为每次调用
- 空间复杂度:(不计输入存储)。
💡 优化思路:标准前缀和(推荐)
如果题目中 sumRange 被频繁调用,我们应该在初始化时预处理前缀和数组,将查询复杂度降为 。
优化代码
1 | class NumArray: |
优化后性能
- 时间复杂度:
__init__: (预处理)。sumRange: (直接查表)。
- 空间复杂度:(存储前缀和数组)。
思考
-
为什么当前代码能工作?
- 它利用了前缀和的数学定义 。
- Python 的
sum()函数和切片语法[:k]非常强大,掩盖了底层的遍历过程。
-
当前代码的隐患:
- 如果
nums长度很大(例如 ),且sumRange被调用 次,总运算次数将达到 ,会导致超时。 - 面试中通常期望看到“预处理 + 查询”的标准前缀和解法。
- 如果
-
边界处理:
- 当
left = 0时,self.nums[:0]是空列表,sum为 0,逻辑正确。
- 当
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 笺札!






