差分数组模板

差分数组模板参考于labuladong:论那些小而美的算法技巧:差分数组一、什么时候使用差分数组呢?相信很多人都遇到过这类题:给定一个原数组长度为n,查询次数m,每次查询给定一个区间[l,r]和一个整数k,使得原数组介于[l,r]之间的元素同时增(或减)k输出最终的数组num[8,2,6,3,1]m=2131023注:第一次查询num=83741第二次查询num=1161041最终num=1

大家好,又见面了,我是你们的朋友全栈君。

参考于 labuladong: 论那些小而美的算法技巧:差分数组

一、什么时候使用差分数组呢?

相信很多人都遇到过这类题:
给定一个原数组长度为 n,查询次数 m ,
每次查询给定一个区间 [l ,r] 和一个整数 k , 使得原数组介于 [l ,r] 之间的元素同时 增 (或减) k
输出最终的数组

num[ 8 , 2 , 6 , 3 , 1 ] m = 2
1 3 1
0 2 3
注:
第一次查询 num = 8 3 7 4 1
第二次查询 num = 11 6 10 4 1
最终 num = 11 6 10 4 1

当然了,每次查询,遍历一下区间 [l ,r] 对其进行修改,结果肯定是对的
但是呢,笔试 和 刷题 时,如果数据给的比较大,比较严苛,多数是会超时,时间复杂度是 O(mn)

二、什么是差分数组 ?

这时就需要用到了差分数组的技巧来解答,
差分数组 : 主要适用场景是频繁对原始数组的某个区间的元素进行增减。
1、首先 构造差分数组 diff ,diff [ i ] = num [ i ] – num [ i – 1 ]

int[] diff = new int[nums.length];
// 构造差分数组
diff[0] = nums[0];
for (int i = 1; i < nums.length; i++) { 
   
    diff[i] = nums[i] - nums[i - 1];
}

在这里插入图片描述
通过这个diff差分数组是可以反推出原始数组nums的,代码逻辑如下:

int[] res = new int[diff.length];
// 根据差分数组构造结果数组
res[0] = diff[0];
for (int i = 1; i < diff.length; i++) { 
   
    res[i] = res[i - 1] + diff[i];
}

2、这样构造差分数组 diff,就可以 快速进行区间增减的操作,如果你想对 区间 [ i , j ] 的元素全部加 3,那么只需要让 diff[ i ] += 3,然后再让 diff[ j + 1 ] -= 3 即可:
在这里插入图片描述
原理很简单,回想 diff 数组反推 nums 数组的过程diff [ i ] += 3 意味着给 nums [ i… ] 所有的元素都加了 3,然后 diff [ j + 1 ] -= 3 又意味着对于 nums [ j + 1… ] 所有元素再减 3,那综合起来,是不是就是对 nums [ i … j ] 中的所有元素都加 3 了 。
只要花费 O(1) 的时间修改 diff 数组,就相当于给 nums 的整个区间做了修改。多次修改diff,然后通过 diff 数组反推,即可得到 nums 修改后的结果。

class Difference { 
   
    // 差分数组
    private int[] diff;
    public Difference(int[] nums) { 
   
        assert nums.length > 0;
        diff = new int[nums.length];
        // 构造差分数组
        diff[0] = nums[0];
        for (int i = 1; i < nums.length; i++) { 
   
            diff[i] = nums[i] - nums[i - 1];
        }
    }
    /* 给闭区间 [i,j] 增加 val(可以是负数)*/
    public void increment(int i, int j, int val) { 
   
        diff[i] += val;
        if (j + 1 < diff.length) { 
   
            diff[j + 1] -= val;
        }
    }
    public int[] result() { 
   
        int[] res = new int[diff.length];
        // 根据差分数组构造结果数组
        res[0] = diff[0];
        for (int i = 1; i < diff.length; i++) { 
   
            res[i] = res[i - 1] + diff[i];
        }
        return res;
    }
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

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

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


相关推荐

  • 国外迅雷下载太慢怎么办_迅雷下载宝还能用吗

    国外迅雷下载太慢怎么办_迅雷下载宝还能用吗复制下载链接,用百度网盘离线下载到网盘内,然后从网盘直接下载,速度相当给力

    2025年9月28日
    3
  • 大唐电信提交两项大数据与云计算标准在ITU-T获立项

    大唐电信提交两项大数据与云计算标准在ITU-T获立项

    2022年4月2日
    40
  • leetcode 回文数_将一个整数转换为字符串

    leetcode 回文数_将一个整数转换为字符串原题链接请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。函数 myAtoi(string s) 的算法如下:读入字符串并丢弃无用的前导空格检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。将前面步骤读入的这些数字转换为整数(即,“1

    2022年8月9日
    6
  • PyCharm入门教程——用户界面导览「建议收藏」

    PyCharm入门教程——用户界面导览「建议收藏」JetBrainsPyCharm是一种PythonIDE,其带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具。此外,该IDE提供了一些高级功能,以用于Django框架下的专业Web开发。通过这篇文章,您可以了解PyCharm用户界面是如何组织的,以帮助您在工作环境中找到自己的方式。当您第一次运行PyCharm或没有打开任何项目时,PyCharm将显示欢迎屏幕,允许快速…

    2022年8月28日
    4
  • idea启动tomcat日志乱码

    idea启动tomcat日志乱码乱码样式:解决方案:如下图设置tomcat1.代码:-Dfile.encoding=UTF-82.进入设置界面:set—>editor—>fileencoding(全部设置为UTF-8)*(最重要)3.进入idea的安装文件中,bin文件下,修改idea.exe.vmoptions和idea64.exe.vmop…

    2022年6月20日
    64
  • LoadRunner压力测试实例步骤

    LoadRunner压力测试实例步骤LoadRunner 是一种预测系统行为和性能的工业标准级负载测试工具。通过以模拟上千万用户实施并发负载及实时性能监测的方式来确认和查找问题,LoadRunner 能够对整个企业架构进行测试。通过使用LoadRunner , 企业能最大限度地缩短测试时间, 优化性能和加速应用系统的发布周期。目前企业的网络应用环境都必须支持大量用户,网络体系架构中含各类应用环境且由不同供应商提供软件和硬件产品。难以…

    2022年7月18日
    17

发表回复

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

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