题目

题目

思路

一看就是单点更新和区间求和,故用线段树做。

一开始没搞清楚,题目给定的i是从0开始还是从1开始,还以为是从1开始,导致后面把下标都改掉了,还有用区间更新的代码去实现单点更新,虽然两者思路是一样的,但是导致TLE,因为区间会把所有都递归一遍,加了个判断,就ok了。

if (idx <= middle) {
this->updateHelper(curIdx << 1, leftIdx, middle, idx, val);
}
else {
this->updateHelper((curIdx << 1) | 1, middle+1, rightIdx, idx, val);
}

实现

//

#include "../PreLoad.h"

class Solution {
public:
class NumArray {
public:
struct Node {
int val;
int sum;
}; vector<Node> nodes;
vector<int> nums; NumArray(vector<int> nums) {
this->nums = nums;
this->nodes.reserve(4 * nums.size());
for (int i = 1; i <= 4 * nums.size(); i++) {
Node node;
node.val = 0;
node.sum = 0;
this->nodes.push_back(node);
} this->buildTree(1, 1, (int)nums.size());
} // 单点更新
void update(int i, int val) {
if (i < 0 || i > this->nums.size()) {
return ;
} this->updateHelper(1, 1, (int)this->nums.size(), i+1, val);
this->nums[i] = val;
} int sumRange(int i, int j) {
if (i > j) {
return 0;
} return this->sumHelper(1, 1, (int)this->nums.size(), i+1, j+1);
} protected:
void buildTree(int curIdx, int leftIdx, int rightIdx) {
if (leftIdx == rightIdx) {
this->nodes[curIdx].val = this->nums[leftIdx-1];
this->nodes[curIdx].sum = this->nums[leftIdx-1];
return ;
}
else if (leftIdx > rightIdx) {
return ;
} int middle = (leftIdx + rightIdx) / 2;
this->buildTree(curIdx << 1, leftIdx, middle);
this->buildTree((curIdx << 1) | 1, middle+1, rightIdx); this->updateFromSon(curIdx);
} void updateFromSon(int curIdx) {
int leftIdx = curIdx << 1;
int rightIdx = leftIdx | 1; this->nodes[curIdx].sum = this->nodes[leftIdx].sum + this->nodes[rightIdx].sum;
} int sumHelper(int curIdx, int leftIdx, int rightIdx, int leftRange, int rightRange) {
// 不在范围内
if (leftIdx > rightRange || rightIdx < leftRange) {
return 0;
} // 在范围内
if (leftIdx >= leftRange && rightIdx <= rightRange) {
return this->nodes[curIdx].sum;
} int middle = (leftIdx + rightIdx) / 2;
int left = sumHelper(curIdx << 1, leftIdx, middle, leftRange, rightRange);
int right = sumHelper((curIdx << 1) | 1, middle+1, rightIdx, leftRange, rightRange);
return left + right;
} void updateHelper(int curIdx, int leftIdx, int rightIdx, int idx, int val) {
if (leftIdx > rightIdx) {
return;
} if (leftIdx == rightIdx) {
if (idx == leftIdx) {
this->nodes[curIdx].val = val;
this->nodes[curIdx].sum = val;
}
return ;
} int middle = (leftIdx + rightIdx) / 2;
if (idx <= middle) {
this->updateHelper(curIdx << 1, leftIdx, middle, idx, val);
}
else {
this->updateHelper((curIdx << 1) | 1, middle+1, rightIdx, idx, val);
} this->updateFromSon(curIdx);
}
}; void test() {
vector<int> nums = {7, 2, 7, 2, 0}; NumArray *obj = new NumArray(nums);
int idx, val;
while (cin >> idx >> val) {
obj->update(idx, val); int sum = obj->sumRange(0, 4);
cout << "sum: " << sum << endl;
}
}
};
/**
* Your NumArray object will be instantiated and called as such:
* NumArray obj = new NumArray(nums);
* obj.update(i,val);
* int param_2 = obj.sumRange(i,j);
*/

[LeetCode] Range Sum Query - Mutable 题解的更多相关文章

  1. [LeetCode] Range Sum Query - Mutable 区域和检索 - 可变

    Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...

  2. Leetcode: Range Sum Query - Mutable && Summary: Segment Tree

    Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...

  3. [Leetcode Week16]Range Sum Query - Mutable

    Range Sum Query - Mutable 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/range-sum-query-mutable/de ...

  4. LeetCode Range Sum Query 2D - Mutable

    原题链接在这里:https://leetcode.com/problems/range-sum-query-2d-mutable/ 题目: Given a 2D matrix matrix, find ...

  5. [LeetCode] Range Sum Query 2D - Mutable 二维区域和检索 - 可变

    Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper lef ...

  6. 【刷题-LeetCode】307. Range Sum Query - Mutable

    Range Sum Query - Mutable Given an integer array nums, find the sum of the elements between indices ...

  7. [LeetCode] Range Sum Query 2D - Immutable 二维区域和检索 - 不可变

    Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper lef ...

  8. [LeetCode] Range Sum Query - Immutable 区域和检索 - 不可变

    Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...

  9. [LeetCode] 307. Range Sum Query - Mutable 区域和检索 - 可变

    Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...

随机推荐

  1. Linux 菜鸟学习笔记--系统分区

    硬盘分区 常识 主分区:最多只能有4个 扩展分区:用于突破主分区最多4个的限制 *最多只能有1个 *主分区+扩展分区最多有4个 *不能写入数据,只能包含逻辑分区 逻辑分区 格式化:实际是写入文件系统, ...

  2. 蓝桥网试题 java 基础练习 特殊的数字

    -------------------------------------------------------- 笑脸 :-) ------------------------------------ ...

  3. Activity启动过程分析

    Android的四大组件中除了BroadCastReceiver以外,其他三种组件都必须在AndroidManifest中注册,对于BroadCastReceiver来说,它既可以在AndroidMa ...

  4. HDU 3785 寻找大富翁

    寻找大富翁 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  5. 【12c】扩展数据类型(Extended Data Types)-- MAX_STRING_SIZE

    [12c]扩展数据类型(Extended Data Types)-- MAX_STRING_SIZE 在12c中,与早期版本相比,诸如VARCHAR2, NAVARCHAR2以及 RAW这些数据类型的 ...

  6. js字符串转日期,js字符串解析成日期,js日期解析, Date.parse小时是8点,Date.parse时间多了8小时

    js字符串转日期,js字符串解析成日期,js日期解析, Date.parse小时是8点,Date.parse时间多了8小时 >>>>>>>>>&g ...

  7. Android灯光系统--深入理解背光灯

    Android灯光系统--深入理解背光灯 一.怎么控制背光灯(简述) APP将亮度值写入数据库 线程检测数据库的值是否发生变化 这种机制成为"内容观察者"--contentObse ...

  8. 如何修改Window系统下PATH路径以及win8下masm32V11

    如何修改Window系统下PATH路径   //其实这个都是临时性的, 退出dos窗口就没有用了,只是做个笔记罢了   C:\Users\Administrator>    set path=E ...

  9. BOM元素之location对象

    location对象提供了与当前窗口中加载的文档有关的信息,还提供了一些导航功能,它既是window对象的属性,也是document对象的属性:换句话说,window.location和documen ...

  10. 定义 : angular view 和controller 之前的 ng-init 由谁来负责

    在设计view时,会需要default的值,这是会去下ng-init,但是如果发现ng-init没有,这时controller就会有. 概念是当ctrl要用时,就由ctrl负责.