地址 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. Java时区问题

    Java时区相关 时间格式 UTC是以原子时计时,更加精准,适应现代社会的精确计时.不过一般使用不需要精确到秒时,视为等同.GMT是前世界标准时,UTC是现世界标准时.每年格林尼治天文台会发调时信息, ...

  2. CODING 2.0 企业级持续交付解决方案

    "The key to DevOps transformation is that there is no end-state-we must continuously evolve.&qu ...

  3. 字典 dict方法

    字典 student = {'sId': '1101', 'sName': '张三', 'sClass': '软件测试', 'sColl': '信息技术学院'} # 根据键查询 若不存在会报错 pri ...

  4. redis cluster集群动态伸缩--删除主从节点

    目标:从集群中剔除一组主从(5007,5008) 经过上一节增加5007,5008主从服务节点后,目前集群的情况是这样的: b3363a81c3c59d57143cd3323481259c044e66 ...

  5. [PHP] socket客户端时的超时问题

    连接socket分为连接超时和读取超时 $sock=stream_socket_client("www.google.com:80", $errno,$errstr,2);    ...

  6. 06-Node.js学习笔记-创建web服务器

    创建web服务器 //引用系统模块 const http = require('http'); //创建web服务器 //用于处理url地址 const url = require('url'); c ...

  7. JS Proxy(代理)

    前言 Proxy 也就是代理,可以帮助我们完成很多事情,例如对数据的处理,对构造函数的处理,对数据的验证,说白了,就是在我们访问对象前添加了一层拦截,可以过滤很多操作,而这些过滤,由你来定义. 想了解 ...

  8. Feign Ribbon Hystrix 三者关系 | 史上最全, 深度解析

    史上最全: Feign Ribbon Hystrix 三者关系 | 深度解析 疯狂创客圈 Java 分布式聊天室[ 亿级流量]实战系列之 -25[ 博客园 总入口 ] 前言 疯狂创客圈(笔者尼恩创建的 ...

  9. LeetCode 652: 寻找重复的子树 Find Duplicate Subtrees

    LeetCode 652: 寻找重复的子树 Find Duplicate Subtrees 题目: 给定一棵二叉树,返回所有重复的子树.对于同一类的重复子树,你只需要返回其中任意一棵的根结点即可. 两 ...

  10. C# OpenCVSharp使用SetMouseCallback设置回调方法,报错"向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们。"

    一.描述问题 当非托管代码调用托管应用程序的委托的时候,经常会报错“托管调试助手 "CallbackOnCollectedDelegate"   Message=托管调试助手 &q ...