[LeetCode] Range Sum Query - Mutable 题解
题目
思路
一看就是单点更新和区间求和,故用线段树做。
一开始没搞清楚,题目给定的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 题解的更多相关文章
- [LeetCode] Range Sum Query - Mutable 区域和检索 - 可变
Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...
- 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 ...
- [Leetcode Week16]Range Sum Query - Mutable
Range Sum Query - Mutable 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/range-sum-query-mutable/de ...
- LeetCode Range Sum Query 2D - Mutable
原题链接在这里:https://leetcode.com/problems/range-sum-query-2d-mutable/ 题目: Given a 2D matrix matrix, find ...
- [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 ...
- 【刷题-LeetCode】307. Range Sum Query - Mutable
Range Sum Query - Mutable Given an integer array nums, find the sum of the elements between indices ...
- [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 ...
- [LeetCode] Range Sum Query - Immutable 区域和检索 - 不可变
Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...
- [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 ...
随机推荐
- SQL Server 安装报错找不到vc_red.msi
问题描述: 今天给 WIN 7 SP1 操作系统安装 SQL Server 2014 ,报错找不到vc_red.msi (图片来源网络,请忽略2012字样..) 问题解决: 1.由于安装程序提 ...
- css3 3d 与案例分析
作者:魔洁 聊到3d那我们就先聊聊空间维度,首先一维,比如一条线就是一个一维空间,连点成线在这个空间里这些点只能前进后退,二维空间就是一个平面,这时点不仅可以前进后退还可以左右移动,3维空间也可以说是 ...
- Linux 6.4 partprobe出现warning问题
今天在给服务器做LVM的时候(服务器的系统是CentOS 6.3),用fdisk分区之后,用w写入分区表的时候,就提示Command (m for help): wThe partition tabl ...
- Spark源码分析之Spark Shell(上)
终于开始看Spark源码了,先从最常用的spark-shell脚本开始吧.不要觉得一个启动脚本有什么东东,其实里面还是有很多知识点的.另外,从启动脚本入手,是寻找代码入口最简单的方法,很多开源框架,其 ...
- 一个技术汪的开源梦 —— 微信开发工具包(WeixinSDK)
由于春节的关系 WeixinSDK 这个开源项目的进展比预期推迟了大约一个月的时间,值得高兴的是到目前为止该项目的重要模块已经开发完毕. - 关于项目 该项目的背景是现在微信公众号.微信服务号乃至微 ...
- 前端开发面试题总结之——CSS3
____________________________________________________________________________________________ 相关知识点 布 ...
- <context:component-scan>详解
默认情况下,<context:component-scan>查找使用构造型(stereotype)注解所标注的类,如@Component(组件),@Service(服务),@Control ...
- CSS3的属性为什么要带前缀
使用过CSS3属性的同学都知道,CSS3属性都需要带各浏览器的前缀,甚至到现在,依然还有很多属性需要带前缀.这是为什么呢? 我的理解是,浏览器厂商以前就一直在实施CSS3,但它还未成为真正的标准.为此 ...
- jquery和javascript的区别(常用方法比较)
jquery 就对javascript的一个扩展,封装,就是让javascript更好用,更简单.人家怎么说的来着,jquery就是要用更少的代码,漂亮的完成更多的功能.JavaScript 与JQu ...
- 如何在网上得到你想要的图片,如logo
比如我们想得到网页:http://www.ahnu.edu.cn/里的安徽师范大学logo,可以这样做: 1.Ctrl+U,便进入了网页源代码页,也可以鼠标右键点"查看网页源代码" ...