题目:
给你一个数组 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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/range-sum-query-mutable
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
结果:
方法一:暴力法(无法通过,超时)
方法二:树状数组
解题思路:
方法一:暴力法
暴力法真的就不用说了,就按照题目要求写就可以。但是这个方法会超时。
方法二:树状数组
树状数组我也是先看题解,然后了解了下才明白其妙用。
当一个数字变化的时候,它对应的父节点也会产生变化。
树状数组学习参考:树状数组 数据结构详解与模板(可能是最详细的了)_bestsort的博客-CSDN博客_树状数组
这位大大的博客用图形说明了树状数组,对照这个图就能够理解我们这题是怎么做的啦!
代码:
方法一:
typedef struct {
int numsSize;
int *nums;
} NumArray;
NumArray* numArrayCreate(int* nums, int numsSize) {
NumArray *obj = (NumArray *)malloc(sizeof(NumArray));
//obj->nums = (int *)malloc(sizeof(int) * numsSize);
obj->numsSize = numsSize;
obj->nums = nums;
//for (int i = 0; i < numsSize; i++) {
// obj->nums[i] = nums[i];
//}
return obj;
}
void numArrayUpdate(NumArray* obj, int index, int val) {
obj->nums[index] = val;
}
int numArraySumRange(NumArray* obj, int left, int right) {
int sum = 0;
for (; left <= right; left++, right--) {
if (left != right) {
sum = sum + obj->nums[left] + obj->nums[right];
} else {
sum += obj->nums[left];
}
}
return sum;
}
void numArrayFree(NumArray* obj) {
//free(obj->nums);
free(obj);
obj = NULL;
}
/**
* Your NumArray struct will be instantiated and called as such:
* NumArray* obj = numArrayCreate(nums, numsSize);
* numArrayUpdate(obj, index, val);
* int param_2 = numArraySumRange(obj, left, right);
* numArrayFree(obj);
*/
方法二:
typedef struct {
int treeSize;
int *nums;
int *tree;
} NumArray;
int lowBit(int a)
{
return a & (-a);
}
void Add(int *tree, int treeSize, int index, int value)
{
while (index < treeSize) {
tree[index] += value;
index += lowBit(index);
}
}
int Sum(int *tree, int index)
{
int sum = 0;
while (index > 0) {
sum += tree[index];
index -= lowBit(index);
}
return sum;
}
NumArray* numArrayCreate(int* nums, int numsSize) {
NumArray *obj = (NumArray *)malloc(sizeof(NumArray));
obj->treeSize = numsSize + 1;
obj->nums = nums;
obj->tree = (int *)malloc(sizeof(int) * obj->treeSize);
memset(obj->tree, 0, sizeof(int) * obj->treeSize);
for (int i = 0; i < numsSize; i++) {
Add(obj->tree, obj->treeSize, i + 1, nums[i]);
}
return obj;
}
void numArrayUpdate(NumArray* obj, int index, int val) {
Add(obj->tree, obj->treeSize, index + 1, val - obj->nums[index]);
obj->nums[index] = val;
}
int numArraySumRange(NumArray* obj, int left, int right) {
return Sum(obj->tree, right + 1) - Sum(obj->tree, left);
}
void numArrayFree(NumArray* obj) {
free(obj->tree);
free(obj);
obj = NULL;
}
/**
* Your NumArray struct will be instantiated and called as such:
* NumArray* obj = numArrayCreate(nums, numsSize);
* numArrayUpdate(obj, index, val);
* int param_2 = numArraySumRange(obj, left, right);
* numArrayFree(obj);
*/