--- comments: true difficulty: 简单 edit_url: https://github.com/doocs/leetcode/edit/main/solution/0300-0399/0303.Range%20Sum%20Query%20-%20Immutable/README.md tags: - 设计 - 数组 - 前缀和 --- # [303. 区域和检索 - 数组不可变](https://leetcode.cn/problems/range-sum-query-immutable) [English Version](/solution/0300-0399/0303.Range%20Sum%20Query%20-%20Immutable/README_EN.md) ## 题目描述

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

  1. 计算索引 left 和 right (包含 leftright)之间的 nums 元素的 ,其中 left <= right

实现 NumArray 类:

 

示例 1:

输入:
["NumArray", "sumRange", "sumRange", "sumRange"]
[[[-2, 0, 3, -5, 2, -1]], [0, 2], [2, 5], [0, 5]]
输出:
[null, 1, -1, -3]

解释:
NumArray numArray = new NumArray([-2, 0, 3, -5, 2, -1]);
numArray.sumRange(0, 2); // return 1 ((-2) + 0 + 3)
numArray.sumRange(2, 5); // return -1 (3 + (-5) + 2 + (-1)) 
numArray.sumRange(0, 5); // return -3 ((-2) + 0 + 3 + (-5) + 2 + (-1))

 

提示:

## 解法 ### 方法一:前缀和 我们创建一个长度为 $n + 1$ 的前缀和数组 $s$,其中 $s[i]$ 表示前 $i$ 个元素的前缀和,即 $s[i] = \sum_{j=0}^{i-1} nums[j]$,那么索引 $[left, right]$ 之间的元素的和就可以表示为 $s[right + 1] - s[left]$。 初始化前缀和数组 $s$ 的时间复杂度为 $O(n)$,查询的时间复杂度为 $O(1)$。空间复杂度 $O(n)$。 #### Python3 ```python class NumArray: def __init__(self, nums: List[int]): self.s = list(accumulate(nums, initial=0)) def sumRange(self, left: int, right: int) -> int: return self.s[right + 1] - self.s[left] # Your NumArray object will be instantiated and called as such: # obj = NumArray(nums) # param_1 = obj.sumRange(left,right) ``` #### Java ```java class NumArray { private int[] s; public NumArray(int[] nums) { int n = nums.length; s = new int[n + 1]; for (int i = 0; i < n; ++i) { s[i + 1] = s[i] + nums[i]; } } public int sumRange(int left, int right) { return s[right + 1] - s[left]; } } /** * Your NumArray object will be instantiated and called as such: * NumArray obj = new NumArray(nums); * int param_1 = obj.sumRange(left,right); */ ``` #### C++ ```cpp class NumArray { public: NumArray(vector& nums) { int n = nums.size(); s.resize(n + 1); for (int i = 0; i < n; ++i) { s[i + 1] = s[i] + nums[i]; } } int sumRange(int left, int right) { return s[right + 1] - s[left]; } private: vector s; }; /** * Your NumArray object will be instantiated and called as such: * NumArray* obj = new NumArray(nums); * int param_1 = obj->sumRange(left,right); */ ``` #### Go ```go type NumArray struct { s []int } func Constructor(nums []int) NumArray { n := len(nums) s := make([]int, n+1) for i, v := range nums { s[i+1] = s[i] + v } return NumArray{s} } func (this *NumArray) SumRange(left int, right int) int { return this.s[right+1] - this.s[left] } /** * Your NumArray object will be instantiated and called as such: * obj := Constructor(nums); * param_1 := obj.SumRange(left,right); */ ``` #### TypeScript ```ts class NumArray { private s: number[]; constructor(nums: number[]) { const n = nums.length; this.s = Array(n + 1).fill(0); for (let i = 0; i < n; ++i) { this.s[i + 1] = this.s[i] + nums[i]; } } sumRange(left: number, right: number): number { return this.s[right + 1] - this.s[left]; } } /** * Your NumArray object will be instantiated and called as such: * var obj = new NumArray(nums) * var param_1 = obj.sumRange(left,right) */ ``` #### Rust ```rust struct NumArray { s: Vec, } /** * `&self` means the method takes an immutable reference. * If you need a mutable reference, change it to `&mut self` instead. */ impl NumArray { fn new(mut nums: Vec) -> Self { let n = nums.len(); let mut s = vec![0; n + 1]; for i in 0..n { s[i + 1] = s[i] + nums[i]; } Self { s } } fn sum_range(&self, left: i32, right: i32) -> i32 { self.s[(right + 1) as usize] - self.s[left as usize] } } ``` #### JavaScript ```js /** * @param {number[]} nums */ var NumArray = function (nums) { const n = nums.length; this.s = Array(n + 1).fill(0); for (let i = 0; i < n; ++i) { this.s[i + 1] = this.s[i] + nums[i]; } }; /** * @param {number} left * @param {number} right * @return {number} */ NumArray.prototype.sumRange = function (left, right) { return this.s[right + 1] - this.s[left]; }; /** * Your NumArray object will be instantiated and called as such: * var obj = new NumArray(nums) * var param_1 = obj.sumRange(left,right) */ ``` #### PHP ```php class NumArray { /** * @param Integer[] $nums */ function __construct($nums) { $this->s = [0]; foreach ($nums as $x) { $this->s[] = $this->s[count($this->s) - 1] + $x; } } /** * @param Integer $left * @param Integer $right * @return Integer */ function sumRange($left, $right) { return $this->s[$right + 1] - $this->s[$left]; } } /** * Your NumArray object will be instantiated and called as such: * $obj = NumArray($nums); * $ret_1 = $obj->sumRange($left, $right); */ ``` #### C ```c typedef struct { int* s; } NumArray; NumArray* numArrayCreate(int* nums, int n) { int* s = malloc(sizeof(int) * (n + 1)); s[0] = 0; for (int i = 0; i < n; i++) { s[i + 1] = s[i] + nums[i]; } NumArray* obj = malloc(sizeof(NumArray)); obj->s = s; return obj; } int numArraySumRange(NumArray* obj, int left, int right) { return obj->s[right + 1] - obj->s[left]; } void numArrayFree(NumArray* obj) { free(obj->s); free(obj); } /** * Your NumArray struct will be instantiated and called as such: * NumArray* obj = numArrayCreate(nums, numsSize); * int param_1 = numArraySumRange(obj, left, right); * numArrayFree(obj); */ ``` #### Kotlin ```kotlin class NumArray(nums: IntArray) { private val prefix_sums: IntArray init { val nums_size = nums.size this.prefix_sums = IntArray(nums_size + 1) for (i in 0..