差分数组
简介
差分数组是一种对频繁修改区间数据(频繁对一个区间中的每一个元素进行修改)问题的一种优化时间复杂度的操作(空间换时间)。
假如有一个很大的数据a.size = 1e+999,需要多次对一个特定的区间[left,right]中的所有数据加上或减去一个固定的数值。一个通常的做法是进行模拟,依次对a[left]~a[right]中的每一个数据进行增加或删除操作,其时间复杂度为\(O(n*max(right-left))\),其中\(n\)为操作次数。若采用差分数组,其时间复杂度为\(O(n+l)\),其中\(n\)为查询次数,\(l\)为差分数组长度。以下为其主要思想。
Method
a为初始未进行任何操作的数组;- 建立差分数组
diff,其尺寸与a一致,diff[0]=a[0];diff[i]=a[i]-a[i-1],即记录a中相邻元素的差值; - 当对
a中的区间[left,right]进行一次修改操作时(例如增加x),仅需diff[left]+=x;diff[right+1]-=x,diff中的其他数据不需要进行变动,因为对整个区间做修改仅仅会影响到边界的差值,其他位置的差值保持不变,每一次修改的时间复杂度为\(O(1)\); - 多次修改操作后需要将差分数组变换成原数组修改后的数组,根据差分数组的性质,直接求差分数组的前缀和即可得到修改后的数组。
简单差分示例:

例子
(取自leetcode1893)
给你一个二维整数数组 ranges 和两个整数 left和 right 。每个ranges[i] = [starti, endi] 表示一个从 starti到endi的 闭区间 。
如果闭区间[left, right]内每个整数都被ranges中 至少一个 区间覆盖,那么请你返回true ,否则返回 false 。
已知区间 ranges[i] = [starti, endi] ,如果整数x 满足starti <= x <= endi ,那么我们称整数x 被覆盖了。
1 | 示例 1: |
1 | - 示例 2: |
此外,题中限定了输入数据的范围:
1 | 1 <= ranges.length <= 50 |
我们可以据此方便的建立差分数组。
暴力解法
建立一个数组,0代表没有覆盖,1代表有覆盖,遍历ranges中的区间,将a中的可覆盖的索引处都置1,然后遍历a中的[left,right]区间查看是否有0,有则未全覆盖,无则全覆盖。
1 | class Solution: |
差分数组解法
1 | class Solution: |