[LeetCode] Range Addition 范围相加
Assume you have an array of length n initialized with all 0's and are given k update operations.
Each operation is represented as a triplet: [startIndex, endIndex, inc] which increments each element of subarray A[startIndex ... endIndex] (startIndex and endIndex inclusive) with inc.
Return the modified array after all k operations were executed.
Example:
Given:
length = 5,
updates = [
[1, 3, 2],
[2, 4, 3],
[0, 2, -2]
]
Output:
[-2, 0, 3, 5, 3]
Explanation:
Initial state:
[ 0, 0, 0, 0, 0 ] After applying operation [1, 3, 2]:
[ 0, 2, 2, 2, 0 ] After applying operation [2, 4, 3]:
[ 0, 2, 5, 5, 3 ] After applying operation [0, 2, -2]:
[-2, 0, 3, 5, 3 ]
Hint:
- Thinking of using advanced data structures? You are thinking it too complicated.
- For each update operation, do you really need to update all elements between i and j?
- Update only the first and end element is sufficient.
- The optimal time complexity is O(k + n) and uses O(1) extra space.
Credits:
Special thanks to @vinod23 for adding this problem and creating all test cases.
这道题刚添加的时候我就看到了,当时只有1个提交,0个接受,于是我赶紧做,提交成功后发现我是第一个提交成功的,哈哈,头一次做沙发啊,有点小激动~ 这道题的提示说了我们肯定不能把范围内的所有数字都更新,而是只更新开头结尾两个数字就行了,那该怎么做呢?假设我们的数组范围是 [0, n),需要更新的区间是 [start, end],更新值是 inc,那么将区间 [start, end] 中每个数字加上 inc,等同于将区间 [start, n) 内的数字都加上 inc,然后将 [end+1, n) 区间内数字都减去 inc,明白了可以这样转换之后,我们还是不能每次都更新区间内所有的值,所以需要换一种标记方式,做法就是在开头坐标 start 位置加上 inc,而在结束位置 end 加1的地方加上 -inc。就比如说需要将新区间 [1, 3] 内数字都加2,那么我们在1的位置加2,在4的位置减2,于是数组就变成了 [0, 2, 0, 0, -2]。假如就只有这一个操作,如何得到最终的结果呢,答案是建立累加和数组,变成 [0, 2, 2, 2, 0],我们发现正好等同于直接将区间 [1, 3] 内的数字都加2。进一步分析,建立累加和数组的操作实际上是表示当前的数字对之后的所有位置上的数字都有影响,那么我们在 start 位置上加了2,表示在 [start, n) 区间范围内每个数字都加了2,而实际上只有 [start, end] 区间内的数字才需要加2,为了消除这种影响,我们需要将 [end+1, n) 区间内的数字都减去2,所以才在 end+1 位置上减去了2,那么建立累加和数组的时候就相当于后面所有的数字都减去了2。需要注意的是这里 end 可能等于 n-1,则 end+1 可能会越界,所以我们初始化数组的长度为 n+1,就可以避免越界了。那么根据题目中的例子,我们可以得到一个数组,nums = {-2, 2, 3, 2, -2, -3},然后对其做累加和就是我们要求的结果 result = {-2, 0, 3, 5, 3},参见代码如下:
解法一:
class Solution {
public:
vector<int> getModifiedArray(int length, vector<vector<int>>& updates) {
vector<int> res, nums(length + , );
for (int i = ; i < updates.size(); ++i) {
nums[updates[i][]] += updates[i][];
nums[updates[i][] + ] -= updates[i][];
}
int sum = ;
for (int i = ; i < length; ++i) {
sum += nums[i];
res.push_back(sum);
}
return res;
}
};
我们可以在空间上稍稍优化下上面的代码,用 res 来代替 nums,最后把 res 中最后一个数字去掉即可,参见代码如下:
解法二:
class Solution {
public:
vector<int> getModifiedArray(int length, vector<vector<int>>& updates) {
vector<int> res(length + );
for (auto a : updates) {
res[a[]] += a[];
res[a[] + ] -= a[];
}
for (int i = ; i < res.size(); ++i) {
res[i] += res[i - ];
}
res.pop_back();
return res;
}
}
Github 同步地址:
https://github.com/grandyang/leetcode/issues/370
类似题目:
参考资料:
https://leetcode.com/problems/range-addition/
https://leetcode.com/problems/range-addition/discuss/84223/My-Simple-C%2B%2B-Solution
https://leetcode.com/problems/range-addition/discuss/84217/Java-O(K-%2B-N)time-complexity-Solution
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Range Addition 范围相加的更多相关文章
- [LeetCode] 370. Range Addition 范围相加
Assume you have an array of length n initialized with all 0's and are given k update operations. Eac ...
- [LeetCode] Range Addition II 范围相加之二
Given an m * n matrix M initialized with all 0's and several update operations. Operations are repre ...
- LeetCode Range Addition II
原题链接在这里:https://leetcode.com/problems/range-addition-ii/description/ 题目: Given an m * n matrix M ini ...
- Leetcode: Range Addition
Assume you have an array of length n initialized with all 0's and are given k update operations. Eac ...
- [LeetCode] 598. Range Addition II 范围相加之二
Given an m * n matrix M initialized with all 0's and several update operations. Operations are repre ...
- LeetCode: 598 Range Addition II(easy)
题目: Given an m * n matrix M initialized with all 0's and several update operations. Operations are r ...
- LeetCode 445——两数相加 II
1. 题目 2. 解答 2.1 方法一 在 LeetCode 206--反转链表 和 LeetCode 2--两数相加 的基础上,先对两个链表进行反转,然后求出和后再进行反转即可. /** * Def ...
- Leetcode 002. 两数相加
1.题目描述 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表 ...
- 598. Range Addition II 矩阵的范围叠加
[抄题]: Given an m * n matrix M initialized with all 0's and several update operations. Operations are ...
随机推荐
- 你真的会玩SQL吗?三范式、数据完整性
你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...
- 5.C#WinForm基础登陆失败三次退出系统
目标: 登陆界面,登陆错误三次退出程序.假设用户名密码是admin.888888,不区分大小写,(易错点:局部变量与类变量) 局部变量每次运行完毕变量的值都会被销毁,下次再运行,会重新初始化. ...
- jQuery操作DOM元素
作为一个后端程序员,也是要和前端页面打交道的.最常见的场景莫过DOM元素操作和前端页面使用AJAX向服务器发送请求.实现上述两个功能当然可以使用原生js来完成,但在实际开发过程中很少这样做,通常会使用 ...
- 怎么调试lua性能
怎么调试lua性能 我们的游戏使用的是Cocos2dx-lua 3.9的项目,最近发现我们的游戏.运行比较缓慢.想做一次性能优化了.其实主要分为GPU.CPU的分别优化.GPU部分的优化.网上有很多优 ...
- C# 读取app.config配置文件 节点键值,提示 "配置系统未能初始化" 错误的解决方案
新建C#项目,在app.config中添加了appSettings项,运行时出现"配置系统未能初始化"的错误,MSDN里写到,如果配置文件中包含 configSections 元素 ...
- MySQL: Table 'mysql.plugin' doesn't exist的解决
安装解压版MySQL以后,不能启动,日志里面出现了这个错误: MySQL: Table 'mysql.plugin' doesn't exist 这是因为mysql服务启动时候找不到内置数据库&quo ...
- 【挖财工作笔记】idea使用指南
一 安装破解 破解选择服务器,然后选择地址:http://www.iteblog.com/idea/key.php http://idea.iteblog.com/key.php http://i ...
- 在QMainWindow中利用多个QDockWidget构成标签页tab(原创)
功能描述: 在QMainWindow下,使用多个QDockWidget构成可切换,可拖动,可关闭的标签页:标签页的切换由相关联的QAction触发. 实现效果: 代码如下: QDockWidget * ...
- SQLite Expert Professional 3查看SQLite数据
通常在android进行SQLite数据库的处理查看很不方便,于是自己下载了一个SQLite Expert Professional 3可视化工具用来进行查询数据,由于时间问题就不多说了,直接讲使用方 ...
- NSURLConnection实现文件上传和AFNetworking实现文件上传
请求的步骤分为4步 1.创建请求 2.设置请求头(告诉服务器这是一个文件上传的请求) 3.设置请求体 4.发送请求 NSURLConnection实现文件上传 // 1.创建请求 NSURL *url ...