地址 https://leetcode-cn.com/problems/range-sum-query-mutable/

题目描述
给定一个整数数组  nums,求出数组从索引 i 到 j  (i ≤ j) 范围内元素的总和,包含 i,  j 两点。

update(i, val) 函数可以通过将下标为 i 的数值更新为 val,从而对数列进行修改。

示例:

Given nums = [, , ]

sumRange(, ) ->
update(, )
sumRange(, ) ->
说明: 数组仅可以在 update 函数下进行修改。
你可以假设 update 函数与 sumRange 函数的调用次数是均匀分布的。

算法1
区间求和 自然使用 线段树 或者线段数组
这里以线段树为例
以 空间换时间 记录线段之间的和 最大最小值等
由于是树 即使其中一部分元素改变或者某一个元素改变 更改记录也只是log(n)的复杂度

class SegmentTreeNode {
public:
SegmentTreeNode(int start,int end,int sum,
SegmentTreeNode* left = nullptr,
SegmentTreeNode* right = nullptr):
start(start),
end(end),
sum(sum),
left(left),
right(right){}
SegmentTreeNode(const SegmentTreeNode&) = delete;
SegmentTreeNode& operator=(const SegmentTreeNode&) = delete;
~SegmentTreeNode() {
delete left;
delete right;
left = right = nullptr;
} int start;
int end;
int sum;
SegmentTreeNode* left;
SegmentTreeNode* right;
}; class NumArray {
public:
NumArray(vector<int> nums) {
nums_.swap(nums);
if (!nums_.empty())
root_.reset(buildTree(, nums_.size() - ));
} void update(int i, int val) {
updateTree(root_.get(), i, val);
} int sumRange(int i, int j) {
return sumRange(root_.get(), i, j);
}
private:
vector<int> nums_;
std::unique_ptr<SegmentTreeNode> root_; SegmentTreeNode* buildTree(int start, int end) {
if (start == end) {
return new SegmentTreeNode(start, end, nums_[start]);
}
int mid = start + (end - start) / ;
auto left = buildTree(start, mid);
auto right = buildTree(mid + , end);
auto node = new SegmentTreeNode(start, end, left->sum + right->sum,
left, right); return node;
} void updateTree(SegmentTreeNode* root, int i, int val) {
if (root->start == i && root->end == i) {
root->sum = val;
return;
}
int mid = root->start + (root->end - root->start) / ;
if (i <= mid) {
updateTree(root->left, i, val);
}
else {
updateTree(root->right, i, val);
}
root->sum = root->left->sum + root->right->sum;
} int sumRange(SegmentTreeNode* root, int i, int j) {
if (i == root->start && j == root->end) {
return root->sum;
}
int mid = root->start + (root->end - root->start) / ;
if (j <= mid) {
return sumRange(root->left, i, j);
}
else if (i > mid) {
return sumRange(root->right, i, j);
}
else {
return sumRange(root->left, i, mid) + sumRange(root->right, mid + , j);
}
}
};

LeetCode 307. 区域和检索 - 数组可修改的更多相关文章

  1. Java实现 LeetCode 307 区域和检索 - 数组可修改

    307. 区域和检索 - 数组可修改 给定一个整数数组 nums,求出数组从索引 i 到 j (i ≤ j) 范围内元素的总和,包含 i, j 两点. update(i, val) 函数可以通过将下标 ...

  2. Java实现 LeetCode 303 区域和检索 - 数组不可变

    303. 区域和检索 - 数组不可变 给定一个整数数组 nums,求出数组从索引 i 到 j (i ≤ j) 范围内元素的总和,包含 i, j 两点. 示例: 给定 nums = [-2, 0, 3, ...

  3. [Leetcode] 第307题 区域和检索-数组可修改

    参考博客:(LeetCode 307) Range Sum Query - Mutable(Segment Tree) 一.题目描述 给定一个整数数组  nums,求出数组从索引 i 到 j  (i  ...

  4. [Swift]LeetCode307. 区域和检索 - 数组可修改 | Range Sum Query - Mutable

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

  5. LeetCode:区域和检索【303】

    LeetCode:区域和检索[303] 题目描述 给定一个整数数组  nums,求出数组从索引 i 到 j  (i ≤ j) 范围内元素的总和,包含 i,  j 两点. 示例: 给定 nums = [ ...

  6. [Leetcode]303.区域和检索&&304.二维区域和检索

    题目 1.区域和检索: 简单题,前缀和方法 乍一看就觉得应该用前缀和来做,一个数组多次查询. 实现方法: 新建一个private数组prefix_sum[i],用来存储nums前i个数组的和, 需要找 ...

  7. 【leetcode 简单】 第七十九题 区域和检索 - 数组不可变

    给定一个整数数组  nums,求出数组从索引 i 到 j  (i ≤ j) 范围内元素的总和,包含 i,  j 两点. 示例: 给定 nums = [-2, 0, 3, -5, 2, -1],求和函数 ...

  8. [Swift]LeetCode303. 区域和检索 - 数组不可变 | Range Sum Query - Immutable

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

  9. C#LeetCode刷题-树状数组

    树状数组篇 # 题名 刷题 通过率 难度 218 天际线问题   32.7% 困难 307 区域和检索 - 数组可修改   42.3% 中等 315 计算右侧小于当前元素的个数   31.9% 困难 ...

随机推荐

  1. Nlog配置

    初次使用nlog,里里外外找了好久,终于搞会了. 使用nlog建日志输出到txt文件.数据库.邮件 nlog配置,如图 码云dome

  2. Dotnet Core中使用AutoMapper

    官网:http://automapper.org/ 文档:https://automapper.readthedocs.io/en/latest/index.html GitHub:https://g ...

  3. java 线程同步方法执行与唤醒实例

    账号提钱.存钱实例方法 public class Account { private int balance; private int maxBalance; public Account(int b ...

  4. Mac中 pip3 install mysqlclient 报错

    主要错误提示如下: ld: library not found for -lssl clang: error: linker command failed with exit code 1 (use ...

  5. Java_可变参数类型

    Java方法中的可变参数类型,也称为不定参数类型,是一个非常重要的概念 举栗子 public class TestVarArgus { public static void dealArray(int ...

  6. celery执行异步任务和定时任务

    一.什么是Clelery Celery是一个简单.灵活且可靠的,处理大量消息的分布式系统 专注于实时处理的异步任务队列 同时也支持任务调度 Celery架构 Celery的架构由三部分组成,消息中间件 ...

  7. day96_11_28 mongoDB与scrapy框架

    一.mongodb mongodb是一个面向文档的数据库,而不是关系型数据库.不采用关系型是为了获得更好的扩展性. 它与mysql的区别在于它没有表连接,但是可以通过其他办法实现. 安装数据库. 上官 ...

  8. swoole为什么不能代替nginx

    Swoole不能代替Apache和Nginx这些通用的HTTP服务器. 但基于Swoole开发的PHP应用不依赖Apache和Nginx也能提供生产级别的HTTP服务. 有需要学习交流的友人请加入交流 ...

  9. 云数据库MongoDB版清理oplog日志和compact命令详解

    1.问题描述: 今天看到公司mongodb的oplog有点大,看到云数据库MongoDB版日志清理策略. MongoDB数据库在长期频繁地删除/写入数据或批量删除了大量数据,将产生很多物理空间碎片. ...

  10. HBase删除数据的原理

    转自:https://blog.csdn.net/cenjianteng/article/details/96645447 -------------------------------------- ...