【LeetCode】一文吃透差分数组(附例题)

【LeetCode】一文吃透差分数组(附例题)因为我们还原数组时候需要从头开始 是有顺序的 也就是使用 map 代替了数组 注意初始数组都为 0 每次 book 都需要将区间内元素加 1 表示预定次数 然后求得区间元素最大值即为所求 区间更新问题除了最适用的线段树维护之后 还可以使用差分数组维护 顾名思义 差分数组元素就是原数组中两个元素之差 例如假设原数组为 差分数组是把原数组中后一个元素减前一个元素的差构成一个新的数组 作为辅助数组使用 这样就省去了遍历操作 因为原数组的值可以通过差分数组两端的数求得

差分数组深入浅出,一文吃透!

原文同步在:https://github.com/EricPengShuai/Interview/blob/main/algorithm/差分数组.md

0. 概念

区间更新问题除了最适用的线段树维护之后,还可以使用差分数组维护,顾名思义,差分数组元素就是原数组中两个元素之差,例如假设原数组为 arr=[7, 1, 5, 6, 3, 2, 4, 8],那么查分数组就是 arr1=[0, -6, 4, 1, -3, -1, 2, 4],arr1[0] 默认为 0,如下图:

差分数组

差分数组是把原数组中后一个元素减前一个元素的差构成一个新的数组,作为辅助数组使用。具体来说:

// nums 是原数组,diff 是差分数组 diff[0] = nums[0]; diff[1] = nums[1] - nums[0]; diff[2] = nums[2] - nums[1]; ... nums[0] = diff[0]; nums[1] = diff[1] + nums[0] = diff[0] + diff[1]; nums[2] = nums[1] + diff[2] = diff[0] + diff[1] + diff[2]; 

1. 应用

一般来说,将原数组 nums 中 [0, 3] 的值都加2,我们需要遍历对应区间:

for (int i = 0; i < 4; ++ i) { 
    nums[i] += 2; } 

但是使用差分数组我们就只需要更新端点就可以了:

diff[0] += 2; // 0 往后的所有值都加 2 diff[4] -= 2; // 4 往后的所有值都减 2 

这样就省去了遍历操作,因为原数组的值可以通过差分数组两端的数求得。

2. 代码

以 732. 我的日程安排表 III 为例,我们维护有序的STL map,因为我们还原数组时候需要从头开始,是有顺序的,也就是使用 map 代替了数组,注意初始数组都为0,每次 book 都需要将区间内元素加1表示预定次数,然后求得区间元素最大值即为所求

class MyCalendarThree { 
    public: MyCalendarThree() { 
    } int book(int start, int end) { 
    // 注意题目中是前开后闭区间 diff[start]++; // start 开始的值都加 1 diff[end]--; // end 开始的值都减 1 int res = 0; int cur = 0; for( auto & kv : diff ) { 
    cur += kv.second; // 还原原数组,由于初始值都是0所以这里就只是加差分值 res = max(res,cur); // 求预定次数的最大值 } return res; } private: map<int,int> diff; //差分数组 }; / * Your MyCalendarThree object will be instantiated and called as such: * MyCalendarThree* obj = new MyCalendarThree(); * int param_1 = obj->book(start,end); */ 

另外类似题还有:

  • 729. 我的日程安排表 I
  • 731. 我的日程安排表 II

3. 参考

  • C++ 差分数组,注释详细
  • 我的日程安排表 III【差分数组+线段树动态开点(带lazy)】
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/232249.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • JDBC_4数据库连接池[通俗易懂]

    JDBC_4数据库连接池[通俗易懂]数据库连接池JDBC数据库连接池的必要性在使用开发基于数据库的web程序时,传统的模式基本是按照以下步骤:在主程序(如servlet beans)中建立数据库连接进行sql操作断开数据库连接这种模式开发,存在的问题:普通的JDBC数据库连接使用DriverManager来获取,每次向数据库建立连接的时候都要将Connection加载到内存中,再验证用户名和密码(大概花费0.05s-1s),需要数据库连接的时候,就向数据库要求一个,执行完成后再断开。这样的方式将会消耗大量的时间。数据库的

    2022年8月8日
    6
  • RabbitMQ(七):常用方法说明 与 学习小结

    RabbitMQ(七):常用方法说明 与 学习小结

    2021年10月5日
    40
  • gallery的画廊效果

    gallery的画廊效果

    2022年3月2日
    41
  • 弗曼学习法,你在用吗?

    弗曼学习法,你在用吗?今天简单的谈论一下弗曼学习法,是被学术界认为最niubi的学习方法。理查德.弗曼(1918-1988)1965年获得诺贝尔物理学奖,美籍犹太人,也是最早提出纳米的人。之所以以他的名字命名改学习方法,想必不用说大家也都知道了,总之很厉害一个人就是了。 弗曼学习法的原理,可以用一句话来概括(透过现象看本质),比方说我们刚学习、接触一个知识点,按照正常的逻辑就是去学会怎么使用它就行了,而带来的弊端就是,当时,亦或者一段时间内我们能记得,但是随着时间加长,没有使用过这个知识点,我们便会很快就忘记了。因为我

    2022年6月13日
    37
  • 从网页抓取数据的一般方法

    首先要了解对方网页的运行机制 ,这可以用httpwacth或者httplook来看一下http发送和接收的数据。这两个工具应该说是比较简单易懂的。这里就不再介绍了。主要关注的内容是heade

    2021年12月27日
    41
  • centos7.4安装docker_docker打包python应用

    centos7.4安装docker_docker打包python应用前言当我们在一台电脑上搭建了python3.6的环境,下次换台电脑,又得重新搭建一次,设置环境变量等操作。好不容易安装好,一会提示pip不是内部或外部命令,一会又提示pip:commandno

    2022年8月6日
    8

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号