leetcode刷题笔记307题 区域和检索 - 数组可修改
leetcode刷题笔记307题 区域和检索 - 数组可修改
问题描述:
给定一个整数数组 nums,求出数组从索引 i 到 j (i ≤ j) 范围内元素的总和,包含 i, j 两点。
update(i, val) 函数可以通过将下标为 i 的数值更新为 val,从而对数列进行修改。
示例:
Given nums = [1, 3, 5]
sumRange(0, 2) -> 9
update(1, 2)
sumRange(0, 2) -> 8
说明:数组仅可以在 update 函数下进行修改。
你可以假设 update 函数与 sumRange 函数的调用次数是均匀分布的。
//主要使用树状数组处理,树状数组详见https://www.cnblogs.com/xenny/p/9739600.html
//主要是构造三个函数 lowbit() query() add()
class NumArray(nums: Array[Int]) {
val tr = Array.fill(nums.length+1)(0)
val n = nums.length
for (i <- 0 to n-1){
add(i+1, nums(i))
//println(tr.mkString(" "))
}
def lowbit(i: Int): Int = {
return i & (-i)
}
def query(x: Int): Int = {
var res = 0
var i = x
while (i > 0) {
res += tr(i)
i -= lowbit(i)
}
return res
}
def add(x: Int, v:Int): Unit = {
var i = x
while (i <= n) {
tr(i) += v
i += lowbit(i)
}
}
def update(i: Int, value: Int) {
add(i+1, value-nums(i))
nums(i) = value
}
def sumRange(i: Int, j: Int): Int = {
return query(j+1) - query(i)
}
}
/**
* Your NumArray object will be instantiated and called as such:
* var obj = new NumArray(nums)
* obj.update(i,`val`)
* var param_2 = obj.sumRange(i,j)
*/
type NumArray struct {
tr []int
nums []int
}
func lowbit(x int) int {
return x&(-x)
}
func (this *NumArray) Query(x int) int {
res := 0
for i := x; i > 0; i -= lowbit(i) {
res += this.tr[i]
}
return res
}
func (this *NumArray) Add(x int, val int) {
for i := x; i <= len(this.nums); i += lowbit(i){
this.tr[i] += val
}
}
func Constructor(nums []int) NumArray {
newArray := NumArray{make([]int, len(nums)+1),nums}
for i := 0; i < len(nums); i++ {
newArray.Add(i+1, nums[i])
}
return newArray
}
func (this *NumArray) Update(i int, val int) {
this.Add(i+1, val-this.nums[i])
this.nums[i] = val
}
func (this *NumArray) SumRange(i int, j int) int {
return this.Query(j+1) - this.Query(i)
}
/**
* Your NumArray object will be instantiated and called as such:
* obj := Constructor(nums);
* obj.Update(i,val);
* param_2 := obj.SumRange(i,j);
*/