算法之路-------差分数组

这篇具有很好参考价值的文章主要介绍了算法之路-------差分数组。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

差分数组的由来

针对数组中连续的大量数据进行修改的问题,如果我们对每个数据都进行依次修改,对于一些少量的数据的修改(例如:1~100这些的),修改的时候我们发现速度貌似还是很快的,但是一旦修改的连续数组中的数量上万了,那么修改的速率就明显下降了。

所以:针对这样的情况,就出现了差分数组。

差分数组的具体使用

1.差分数组的概念:

①差分数组:其实也就是一个额外的数组(说白了,就是为了挽回时间效率而利用空间去开辟一个数组帮我们更好的去管理一些数据),这个数组是为要改动的目标数组进行数据管理的。

②差分数组与要管理数组的关系:

假设要管理的数据为a,差分数组为d。对于不同的位置为i,那么对于差分数组而言,他每个位置的数为:d[i] = a[i] - a[i-1]。(d与a对应的每个位置的数据关系为:d与a对应位置的数据等于a当前位置减去a当前位置的上一个位置)

2.差分数据的使用方法:

①:首先,我们看下面一个例子:
假设a数组如下:
算法之路-------差分数组
注意:方格里面的是数组存放的数据,而上面的红色数字是对应的下标。

②:然后我们由差分数组概念得到的公式,计算数组a对应的差分数组d如下:
算法之路-------差分数组

然后我们按照1下标的计算,就可以将数组a的差分数组b计算出来,如图上。

3.差分数组的用法:

①:还是上面的例子,假设我们将数组a中从下标1到下标6的数字都要修改一遍,此时如果我们将数组a进行遍历,然后对对应的位置进行修改,这样的话会有点浪费时间,但是有了差分数组的帮助,我们可以可以轻而易举的做到。

②:对于①中要修改的区域(假设我们要将该区域的所有数+1),我们只需将差分数组中下标为1的数+1,和对应下标为7(6+1)的数-1。
所得的情况如下图:

算法之路-------差分数组

修改后如上图所示,修改后我们查看差分数组,我们发现,对于数组a修改了6个位置,而对应的数组d只修改2个位置就可以解决了(所以,我们不禁联想到,如果数组a是一个长达上千的数组,此时要修改的位置数以百计,而我们使用差分数组只需修改2个位置就可以结束战斗了,那这样是不是有点子划算)。

为什么会这样呢?

答:因为对于差分数组而言,他的每个数是对应数组该位置的数减去前一个数的差,所以我们对于同时做相同的修改数组的连续的数时,对应差分数组这个修改区间的数不需要修改,因为大家都做了相同的改变,所以差是相同的,但是对于边界要进行修改。

①:对于前沿(就是开始修改的位置),因为在原数组中该位置的数修改了,但是该位置前一个数没有修改,并且差分数组的值是原数组中该位置上的值减去前一个数字,所以差分数组这个位置上的值就等于原差分数组的值+要修改的值(带符号)

②:对于后沿(就是修改的结束位置的下一位),因为对于该位置,原数组没有修改值,但是他前一个数字修改了,所以对于差分数组的该位置,应该是原差分数组的值-要修改的值(带符号)。

4.如何利用差分数组的值去得到原数组的值?

①我们知道对于差分数组和原数组的公式如下(a为原数组,d为差分数组):

  • d[i] = a[i] - a[i-1]
  • d[0] = a[0]

从以上的我们可推出,对于每一个a上的对应位置上的数字,我们必须通过累加的形式完成。

拿上面的例子进行举例如下:
算法之路-------差分数组

假设我们要从差分数组d中推出下标为3的原数组a的值为多少,直接从差分数组从下标为0的数加到下标为3的下标即可得到,如上图:3+5+(-5)+(-8)= 11,也就是原数组a中下标为3的数。

②:所以有一下的累加公式,为从差分数组推出原数组:

算法之路-------差分数组
这里其实就是一个累加公式。
其中:sumx为前x项和

具体题目

例如:
力扣题目:731. 我的日程安排表 II
1.题目描述
算法之路-------差分数组
对于这道题,我们发现数据量非常大,所以想到了差分数组的方法。

2.解题思路:

因为对于一个时间段,这个时间段最多只能被选择两次,那么我们完全可以将这个数组设置出来,然后对区间段的值进行加1即可,有了这样的思想,由于数据量实在太大了,所以使用差分数组是非常合适的。

  • 使用map用来保存每个时间段的起始位置和结束位置。(注意用底层为洪红黑树的map表,因为红黑树的map表会进行排序,非常利于我们进行操作)
  • 然后将需要加入的区间加入,加入的时候因为要对区间的数据进行+1,所以对起始位置进行+1,对末尾位置进行-1。(由于此题是左开右闭,所以直接对末尾对应的位置进行-1即可)
  • 然后对map表进行遍历,维护一个数字,用它来统计上面这个数据加进去后,会不出现有某个区间的值会大于2(预约的数量是3)。如果大于,那么该位置就不能加入,直接删除;如果小于,那么就加入。

为什么第三步遍历的时候就能正确的去进行是否可以进行插入的判断呢?

答:这就是我们使用红黑树为底层的map表的作用了,因为对于红黑树而言,他对加入的数据会进行排序,所以加入的数据在遍历的时候一定是从头到尾开始遍历的。而对于一个时间段,开始位置进行+1,而末尾位置进行-1,那么如果在一段区间内,维护的哪个变量变为3了,就证明在该区间内,遇见的开始位置比末尾位置大3,就证明刚才加入的这个区间会出现重复的情况,所以必须删除。

3.解答代码如下:

class MyCalendarTwo {
public:
    map<int,int> map;    //map表
    MyCalendarTwo() {}
    
    bool book(int start, int end) 
    {
        map[start]++;          //起始位置+1
        map[end]--;            //末尾位置-1
        int countlap = 0;      //维护预约计数变量从0开始

        for(auto& [l,r] : map)
        {
            countlap += r;     //因为map是排序过的,直接从第一个位置开始遍历即可
            if(countlap > 2)   //若有区间预约次数大于2了,那么这段时间应该被删除
            {
                map[start]--;
                map[end]++;
                return false;
            }
        }
        return true;
    }
};

差分数组总结文章来源地址https://www.toymoban.com/news/detail-462833.html

  • 适合在数组大量连续数据相同的改变。

到了这里,关于算法之路-------差分数组的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 差分数组 & 技巧小记

      如果两个信息“长得很像”,只要保留一个,对另一个,只要保留它们的差异,然后进行微调就行了。 差分数组: 3210,3208,3206,3211,3220,3212…… 3210 【-2】【-2】【5】【9】【-8】…… 适用场景,频繁对某个区间的元素进行增减。 对区间 nums[i…j] 的元素全部加 5: di

    2024年02月02日
    浏览(24)
  • 差分数组详解

    一维差分数组 假设给你一个数组 nums ,先对区间 [a,b] 中每个元素加 3 ,在对区间 [c,d] 每个元素减 5 …… ,这样非常频繁的区间修改,常规的做法可以一个个计算。 频繁对数组的一段区间进行增加或减去同一个值,如果一个个去操作,很明显效率很差,我们可以使用差分数

    2024年02月08日
    浏览(44)
  • 【差分数组】【图论】【分类讨论】【整除以2】100213按距离统计房屋对数目

    【动态规划】【数学】【C++算法】18赛车 差分数组 图论 分类讨论 整除以2 给你三个 正整数 n 、x 和 y 。 在城市中,存在编号从 1 到 n 的房屋,由 n 条街道相连。对所有 1 = i n ,都存在一条街道连接编号为 i 的房屋与编号为 i + 1 的房屋。另存在一条街道连接编号为 x 的房屋与

    2024年01月22日
    浏览(27)
  • 差分算法介绍

    一、一维差分基本概念 差分算法是前缀和算法的逆运算,可以快速的对数组的某一区间进行计算操作。 例如,有一数列 a[1],a[2],.…a[n],且令 b[i] = a[i]-a[i-1],b[1]=a[1],那么就有 a[i] = b[1]+b[2]+.…+b[i] = a[1]+a[2]-a[1]+a[3]-a[2]+.…+a[i]-a[i-1],此时b数组称作a数组的差分数组 ,换句话来说

    2024年01月25日
    浏览(64)
  • 蓝桥杯一维差分 | 算法基础

    ⭐ 简单说两句 ⭐ ✨ 正在努力的小新~ 💖 超级爱分享,分享各种有趣干货! 👩‍💻 提供:模拟面试 | 简历诊断 | 独家简历模板 🌈 感谢关注,关注了你就是我的超级粉丝啦! 🔒 以下内容仅对你可见~ 作者: 后端小知识 , CSDN后端领域新星创作者 |阿里云专家博主 CSDN 个

    2024年02月03日
    浏览(31)
  • 二维差分算法详解

    二维差分模板 给定一个n行m列的矩阵,下标从1开始。接下来有q次操作,每次操作输入5个参数x1, y1, x2, y2, k,表示把以(x1, y1)为左上角,(x2,y2)为右下角的子矩阵的每个元素都加上k。请输出操作后的矩阵。 第一行包含三个整数n,m,q。接下来n行,每行m个整数,代表矩阵的元素。接

    2024年01月20日
    浏览(27)
  • 差分算法及模板详解

    ⭐写在前面的话:本系列文章旨在复习算法刷题中常用的基础算法与数据结构,配以详细的图例解释,总结相应的代码模板,同时结合例题以达到最佳的学习效果。本专栏面向算法零基础但有一定的C++基础的学习者。若C++基础不牢固,可参考:10min快速回顾C++语法,进行语法

    2023年04月09日
    浏览(46)
  • 【算法基础】前缀和与差分

    😽 PREFACE 🎁欢迎各位→点赞 👍 + 收藏 ⭐ + 评论 📝 📢系列专栏: 算法 💪 种一棵树最好是十年前其次是现在 前缀和指一个数组的某下标之前的所有数组元素的和(包含其自身)。前缀和分为一维前缀和,以及二维前缀和。前缀和是一种重要的预处理,能够降低算法的时

    2024年01月19日
    浏览(26)
  • 算法基础之差分和前缀和

    结论:差分是前缀和的逆运算 举例 一维差分 二维差分 用在一维子区间里的数都增减一个固定值,把对于区间内每个数的操作转换为对于差分数组中的端点的操作,时间复杂度降为o(1)。 用在二维子矩阵里的数都增减一个固定值,把对于子矩阵的每个数的操作转换为对应差分

    2024年02月07日
    浏览(31)
  • 前缀和&差分算法(Python版)

    前缀和与差分是常用的区间优化方式,其中前缀和数组可以将区间查询的时间复杂度降为常数,而差分数组则可以将区间修改的时间复杂度降为常数。 前缀和知识点简单易理解,但出题难度较大,需要根据题意挖掘出潜在的前缀和关系,建立辅助数组求解问题。 (1)一维前

    2024年04月17日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包