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. BaaS API 设计规范

    上个月写了一个团队中的 BaaS API 的设计规范,给大家分享下: 目录 1. 引言... 4 1.1. 概要... 4 1.2. 参考资料... 4 1.3. 阅读对象... 4 1.4. 术语解 ...

  2. C#基础-MD5验证

    一.前言 MD5验证主要用于更新文件功能方面,服务器告知客户端要下载哪些更新文件并提供给客户端其MD5值,客户端从服务器将更新文件下载到本地并计算下载文件的MD5值,将本地接收的MD5值与服务器提供的 ...

  3. 在公有云AZURE上部署私有云AZUREPACK以及WEBSITE CLOUD(二)

    前言 (二)建立虚拟网络环境,以及域控和DNS服务器   1搭建虚拟网络环境 在Azure上创建虚拟网络.本例选择的是东南亚数据中心.后面在创建虚机的时候,也选择这个数据中心. VNet Name: ...

  4. 解决phalcon model在插入或更新时会自动验证非空字段

    在使用phalcon的insert和update功能时,因为数据库所有的字段设置的都是NOT NULL,而phalcon的model在插入或更新之前会自动判断字段是否需要必填,因此导致有空字段时无法存 ...

  5. linux(十三)__vsftpd服务器

    rpm -qa |grep vsftpd yum search vsftpd yum install vsftpd 查看是否已经启动: service vsftpd status 启动: servic ...

  6. struts2中从后台读取数据到<s:select>

    看到网上好多有struts2中从后台读取数据到<s:select>的,但都 不太详细,可能是我自己理解不了吧!所以我自己做了 一个,其中可能 有很多不好的地方,望广大网友指出 结果如图 p ...

  7. mui 手势事件配置

    在开发中监听双击屏幕事件时不起作用,需要在mui.init方法的gestureConfig参数中设置需要监听的手势事件 手势事件配置: 根据使用频率,mui默认会监听部分手势事件,如点击.滑动事件:为 ...

  8. ArcGIS Engine开发之空间查询

    空间查询功能是通过用户选择的空间几何体以及该几何体与当前地图中要素之间的几何关系进行空间查找,从而得到查询结果的操作. 相关类与接口 空间查询相关的类主要是SpatialFilter类,其实现的接口主 ...

  9. app字体被放大效果发虚

    IOS App所有字体被放大,显示效果发虚 小小程序猿 我的博客:http://daycoding.com 分析原因: 由于新版本上线更换了LaunchImage,没有注意美工给的图片尺寸,由于图片尺 ...

  10. android Canvas 和 Paint用法

    自定义view里面的onDraw方法,在这里我们可以绘制各种图形,onDraw里面有两个API我们需要了解清楚他们的用法:Canvas 和 Paint. Canvas翻译成中文就是画布的意思,Canv ...