差分数组
简介
差分数组是一种对频繁修改区间数据(频繁对一个区间中的每一个元素进行修改)问题的一种优化时间复杂度的操作(空间换时间)。
假如有一个很大的数据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: |