307. 区域和检索 - 数组可修改
区域和检索 - 数组可修改
题目描述:
给你一个数组 nums ,请你完成两类查询。
其中一类查询要求 更新 数组 nums 下标对应的值
另一类查询要求返回数组 nums 中索引 left 和索引 right 之间( 包含 )的nums元素的 和 ,其中 left <= right
实现 NumArray 类:
NumArray(int[] nums) 用整数数组 nums 初始化对象
void update(int index, int val) 将 nums[index] 的值 更新 为 val
int sumRange(int left, int right) 返回数组 nums 中索引 left 和索引 right 之间( 包含 )的nums元素的 和 (即,nums[left] + nums[left + 1], …, nums[right])
示例 1:
输入:
[“NumArray”, “sumRange”, “update”, “sumRange”]
[[[1, 3, 5]], [0, 2], [1, 2], [0, 2]]
输出:
[null, 9, null, 8]
解释:
NumArray numArray = new NumArray([1, 3, 5]);
numArray.sumRange(0, 2); // 返回 1 + 3 + 5 = 9
numArray.update(1, 2); // nums = [1,2,5]
numArray.sumRange(0, 2); // 返回 1 + 2 + 5 = 8
提示:
1 <= nums.length <= 3 * 104
-100 <= nums[i] <= 100
0 <= index < nums.length
-100 <= val <= 100
0 <= left <= right < nums.length
调用 pdate 和 sumRange 方法次数不大于 3 * 104
思路:
时间复杂度:O(logn),空间复杂度O(logn)
使用线段数做,构建线段树
代码:
type NumArray []int
func Constructor(nums []int) NumArray {
n := len(nums)
arr := make(NumArray ,n*4)
arr.build(nums,0,0,n-1)
return arr
}
func (this NumArray)build(nums []int, node,s,e int){
if s == e{
this[node] = nums[s]
return
}
m := s+(e-s)/2
this.build(nums,node*2+1,s,m)
this.build(nums,node*2+2,m+1,e)
this[node] = this[node*2+1]+this[node*2 + 2]
}
func (this NumArray)change(idx,val,node,s,e int){
if s == e{
this[node] = val
return
}
m := s+(e-s)/2
if idx <= m{
this.change(idx,val,node*2+1,s,m)
}else{
this.change(idx,val,node*2+2,m+1,e)
}
this[node] = this[node*2+1]+this[node*2+2]
}
func (this NumArray) Update(index int, val int) {
this.change(index,val,0,0,len(this)/4-1)
}
func (seg NumArray) range_(left, right, node, s, e int) int {
if left == s && right == e {
return seg[node]
}
m := s + (e-s)/2
if right <= m {
return seg.range_(left, right, node*2+1, s, m)
}
if left > m {
return seg.range_(left, right, node*2+2, m+1, e)
}
return seg.range_(left, m, node*2+1, s, m) + seg.range_(m+1, right, node*2+2, m+1, e)
}
func (this NumArray) SumRange(left int, right int) int {
return this.range_(left,right,0,0,len(this)/4-1)
}
/**
* Your NumArray object will be instantiated and called as such:
* obj := Constructor(nums);
* obj.Update(index,val);
* param_2 := obj.SumRange(left,right);
*/
代码效率:
执行用时:508 ms, 在所有 Go 提交中击败了51.37%的用户
内存消耗:23.5 MB, 在所有 Go 提交中击败了17.81%的用户
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!