必备知识
前缀和
定义:对前面的数进行求和作为当前项
一维前缀和:
有一个一维数组 和该数组的一维前缀和数组 ,则 和 满足以下关系:
二维前缀和:
有一个二维数组 和该数组的二维前缀和数组 (其同样是个二维数组),则 和 满足以下关系:
差分
定义:当前项减去前一项,d[i] = a[i]-a[i-1] ,差分数组是当前数组项减去数组前一项得出组成新数组。
性质:差分数组求前缀和结果等于原数组
用途:基于差分数组的性质,差分数组最主要用于对数组部分区间进行同时加上或减去一个数。如需要在区间[l,r]同时加上5,只需要在d[l]=d[l]+5,d[r]=d[r]-5即可
案例:
原数组 |
1 |
3 |
3 |
4 |
2 |
6 |
7 |
前缀和 |
1 |
4 |
7 |
11 |
13 |
19 |
26 |
差分 |
1 |
(3-1)= 2 |
(3-3)= 0 |
(4-3)= 1 |
(2-4)= -2 |
(6-2)= 4 |
(7-6)= 1 |
两者关系
对差分数组求前缀和,可以得到原数组,同样的,对前缀和数组求差分,也可以得到原数组
相关题目
前缀和相关题目
525 连续数组
526 连续的子数组和
527 元素和为目标值的子矩阵数量
528 和为k的子数组
529 每个元音包含最长的子字符串
530 统计「优美子数组」 LCP 19:秋叶收藏集
531 矩形区域不超过 K 的最大数值和
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| class Solution { public int findMaxLength(int[] nums) { int maxLength = 0; Map<Integer, Integer> map = new HashMap<Integer, Integer>(); int counter = 0; map.put(counter, -1); int n = nums.length; for (int i = 0; i < n; i++) { int num = nums[i]; if (num == 1) { counter++; } else { counter--; } if (map.containsKey(counter)) { int prevIndex = map.get(counter); maxLength = Math.max(maxLength, i - prevIndex); } else { map.put(counter, i); } } return maxLength; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class Solution { public List<Integer> goodDaysToRobBank(int[] security, int time) { int n = security.length; int[] left = new int[n]; int[] right = new int[n]; for (int i = 1; i < n; i++) { if (security[i] <= security[i - 1]) { left[i] = left[i - 1] + 1; } if (security[n - i - 1] <= security[n - i]) { right[n - i - 1] = right[n - i] + 1; } } List<Integer> ans = new ArrayList<>(); for (int i = time; i < n - time; i++) { if (left[i] >= time && right[i] >= time) { ans.add(i); } } return ans; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| class Solution { public int[] platesBetweenCandles(String s, int[][] queries) { int n = s.length(); int m = queries.length; int[] ret = new int[m]; int[] left = new int[n]; int[] right = new int[n]; int[] preSum = new int[n]; for(int i=0,leftIndex = -1;i<n;i++){ char c = s.charAt(i); if(c=='|')leftIndex = i; left[i] = leftIndex; } for(int i=n-1,rightIndex = -1;i>=0;i--){ char c = s.charAt(i); if(c=='|')rightIndex = i; right[i] = rightIndex; } for(int i=0,sum=0;i<n;i++){ if(s.charAt(i)=='*')sum++; preSum[i]=sum; } for(int i=0;i<m;i++){ int[] arr = queries[i]; int l = arr[0],r = arr[1]; if(left[r]==-1||right[l]==-1||left[r]<=right[l])ret[i]=0; else ret[i]=preSum[left[r]]-preSum[right[l]]; } return ret; } }
|
差分相关题目
相关资料