[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 ...
随机推荐
- console.log("A"-"B"+"3")=?
(点击上方的订阅号,可快速关注,关注有惊喜哦^_^) 前不久看到一道JS基础题目,做了一下竟然错了一半...在此分享一下: 先把题目放上来,大家可以自己测试一下再看答案哦^_^ ①console.lo ...
- ASP.NET Core 中文文档 第二章 指南(3)用 Visual Studio 发布一个 Azure 云 Web 应用程序
原文:Getting Started 作者:Rick Anderson 翻译:谢炀(Kiler) 校对:孟帅洋(书缘).刘怡(AlexLEWIS).何镇汐 设置开发环境 安装最新版本的 Azure S ...
- DNS报文格式(RFC1035)
一.域名和资源记录的定义 1.Name space definitions 2.资源记录定义(RR definitions) 2.1 格式 后面分析报文的时候详细解释. ...
- android 模拟2048
利用节日休息时间在ANDROID上进行学习并模拟2048游戏. 效果如下图: 制作思路: 1.画出2048游戏主界面,根据手机屏幕宽高度进行计算并画出每个方块的大小. @Override protec ...
- EC笔记:第三部分:16成对使用new和delete
我们都知道,申请的资源,使用完毕后要释放.但是这个释放动作,一定要注意. 举个例子,很多人动态分配的资源,在使用之后,往往直接调用了delete,而不管申请资源的时候用的是new还是new[]. 如下 ...
- php函数强大的 strtotime
使用strtotime可以将各种格式的时间字符串转换为时间戳 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 转换常规时间格式 echo date('Y-m-d H:i: ...
- JAVA Thread线程异常监控
一.场景描述:单线程程序可以用try...catch捕获程序的异常,而在多线程程序的时候是无法使用try...catch捕获. 示例1:多线程发生异常,无法使用try...catch捕获问题 publ ...
- IO模型
前言 说到IO模型,都会牵扯到同步.异步.阻塞.非阻塞这几个词.从词的表面上看,很多人都觉得很容易理解.但是细细一想,却总会发现有点摸不着头脑.自己也曾被这几个词弄的迷迷糊糊的,每次看相关资料弄明白了 ...
- 理解Java对象的交互:时钟显示程序
实现: 结构: 对象:时钟 - 对象:小时 - 对象:分钟 小时和分钟具有相同属性(值,上限),可以用一个类Display来定义这两个对象: 但是两者之间又具有联系( ...
- composer 出现 configuration does not allow connection to http.......
出现这样的问题是,镜像使用的是http,而原地址是需要https,所以配置下关掉https就好了. 我们来个全局设置的方法: composer config -g secure-http false ...