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:

  1. Thinking of using advanced data structures? You are thinking it too complicated.
  2. For each update operation, do you really need to update all elements between i and j?
  3. Update only the first and end element is sufficient.
  4. 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

类似题目:

Range Addition II

参考资料:

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

https://leetcode.com/problems/range-addition/discuss/84219/Java-O(n%2Bk)-time-O(1)-space-with-algorithm-explained

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Range Addition 范围相加的更多相关文章

  1. [LeetCode] 370. Range Addition 范围相加

    Assume you have an array of length n initialized with all 0's and are given k update operations. Eac ...

  2. [LeetCode] Range Addition II 范围相加之二

    Given an m * n matrix M initialized with all 0's and several update operations. Operations are repre ...

  3. LeetCode Range Addition II

    原题链接在这里:https://leetcode.com/problems/range-addition-ii/description/ 题目: Given an m * n matrix M ini ...

  4. Leetcode: Range Addition

    Assume you have an array of length n initialized with all 0's and are given k update operations. Eac ...

  5. [LeetCode] 598. Range Addition II 范围相加之二

    Given an m * n matrix M initialized with all 0's and several update operations. Operations are repre ...

  6. LeetCode: 598 Range Addition II(easy)

    题目: Given an m * n matrix M initialized with all 0's and several update operations. Operations are r ...

  7. LeetCode 445——两数相加 II

    1. 题目 2. 解答 2.1 方法一 在 LeetCode 206--反转链表 和 LeetCode 2--两数相加 的基础上,先对两个链表进行反转,然后求出和后再进行反转即可. /** * Def ...

  8. Leetcode 002. 两数相加

    1.题目描述 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表 ...

  9. 598. Range Addition II 矩阵的范围叠加

    [抄题]: Given an m * n matrix M initialized with all 0's and several update operations. Operations are ...

随机推荐

  1. CSS学习笔记——包含块 containing block

    以下内容翻译自CSS 2.1官方文档.网址:https://www.w3.org/TR/CSS2/visudet.html#strut 有时,一个元素的盒子的位置和尺寸根据一个确定的矩形计算,这个确定 ...

  2. NSIS 打包脚本基础

    简介 NSIS(Nullsoft Scriptable Install System)是一个开源的 Windows 系统下安装程序制作程序.它提供了安装.卸载.系统设置.文件解压缩等功能.这如其名字所 ...

  3. CloudNotes之桌面客户端篇:笔记撰写样式的支持

    最近在CloudNotes桌面客户端中新增了笔记撰写样式的功能.当用户新建笔记的时候,可以在输入笔记标题的同时,选择笔记撰写样式,由安装包默认提供的样式主要有默认样式(Default).羊皮纸样式(L ...

  4. WebAPI接收JSON参数注意事项

    运行环境:ASP.NET 4.5.2. 当我们向GlobalConfiguration.Configuration.MessageHandlers添加一个DelegatingHandler派生类后,很 ...

  5. 多线程并发同一个表问题(li)

    现有数据库开发过程中对事务的控制.事务锁.行锁.表锁的发现缺乏必要的方法和手段,通过以下手段可以丰富我们处理开发过程中处理锁问题的方法.For Update和For Update of使用户能够锁定指 ...

  6. java 开发模式

    Java-开发模式 Java Web开发方案有多种,这里列举一些经典的开发模式进行横向比较JSP+JAVABEAN开发模式:    特点:该模式将业务逻辑与页面表现进行分离,在一定程度上增加了程序的可 ...

  7. Canvas的width,height 和 样式中Canvas的width,height

    控制Canvas的大小,有两种方式: 1:直接设置Canvas标签上的书width,height属性值; 2:通过Css设置Canvas的width,height; 这两种方式,区别是很大的. 1:C ...

  8. CentOS7安装docker

    1. 查看系统版本 $ cat /etc/redhat-release   2. 安装docker $  yum install docker 3.检查安装是否成功$ docker version 若 ...

  9. Android Weekly Notes Issue #233

    Android Weekly Issue #233 November 27th, 2016 Android Weekly Issue #233 本期内容包括: 用Mockito做RxJava的单元测试 ...

  10. Socket--Android王国的外交发言人

    Socket:原意"插座",在Java语言中为"套接字" 用于描述IP地址和端口号,是通信链的句柄,我们可以通过它向网络发送请求或者应答网络请求; 它是支持TC ...