持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情
给你一个数组 nums ,请你完成两类查询。
- 其中一类查询要求 更新 数组
nums下标对应的值 - 另一类查询要求返回数组
nums中索引left和索引right之间( 包含 )的nums元素的 和 ,其中left <= right
实现 NumArray 类:
NumArray(int[] nums)用整数数组nums初始化对象void update(int index, int val)将nums[index]的值 更新 为valint 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 * 10^4-100 <= nums[i] <= 1000 <= index < nums.length-100 <= val <= 1000 <= left <= right < nums.length- 调用
update和sumRange方法次数不大于3 * 10^4
解题
/**
* @param {number[]} nums
*/
var NumArray = function (nums) {
const tree = [];
const n = nums.length;
const buildTree = (left, right, idx) => {
if (left === right) {
tree[idx] = nums[left];
} else {
const mid = (left + right) >> 1;
const leftVal = buildTree(left, mid, (idx << 1) + 1);
const rightVal = buildTree(mid + 1, right, (idx << 1) + 2);
tree[idx] = leftVal + rightVal;
}
return tree[idx];
};
buildTree(0, n - 1, 0);
this.tree = tree;
this.nums = nums;
this.length = n;
};
/**
* @param {number} index
* @param {number} val
* @return {void}
*/
NumArray.prototype.update = function (index, val) {
let left = 0;
let right = this.length - 1;
let idx = 0;
const diff = val - this.nums[index];
this.nums[index] = val;
this.tree[idx] += diff;
while (left != right) {
let mid = (left + right) >> 1;
if (mid >= index) {
right = mid;
idx = (idx << 1) + 1;
} else {
left = mid + 1;
idx = (idx << 1) + 2;
}
this.tree[idx] += diff;
}
};
/**
* @param {number} left
* @param {number} right
* @return {number}
*/
NumArray.prototype.sumRange = function (left, right) {
const fn = (l, r, idx) => {
if (l >= left && r <= right) {
return this.tree[idx];
} else if (l > right || r < left) {
return 0;
}
const mid = (l + r) >> 1;
return fn(l, mid, (idx << 1) + 1) + fn(mid + 1, r, (idx << 1) + 2);
};
return fn(0, this.length - 1, 0);
};
/**
* Your NumArray object will be instantiated and called as such:
* var obj = new NumArray(nums)
* obj.update(index,val)
* var param_2 = obj.sumRange(left,right)
*/