Day03 前缀和 | 1248. 统计「优美子数组」、53. 最大子数组和
一、1248. 统计「优美子数组」
1、思路
需要了解前缀和与子段和,奇数看作1,偶数看作 0,求前缀和数组S连续子数组[l,r]中的奇数个数为 S[r]-S[l- 1] = k
先获取前缀和集合,然后再转换为两数之差, 找出s[r] -k 的数据有多少个即可
2、代码
class Solution {public int numberOfSubarrays(int[] nums, int k) {//[0,1,2,2,3,4]// 前缀和// s[i] = s[i - 1] + A[i]// 子段和 sum(l,r) = s[r] - s[l- 1] = kint[] s = new int[nums.length + 1];s[0] = 0;for (int i = 1; i < s.length; i++) {s[i] = s[i - 1] + nums[i - 1] % 2;}int result = 0;Map<Integer, Integer> map = new HashMap();for (int i = 0; i < s.length; i++) {if (map.containsKey(s[i] - k)) {result += map.get(s[i] - k);}map.put(s[i], map.getOrDefault(s[i], 0) + 1);}return result;}
}
二、53. 最大子数组和
1、思路
1、一样先枚举前缀和数组,S[i] = S[i-1 ] + A[i];
子段和 sum(l,r) = s[r] - s[l- 1]
sum(l,r) 需要最大值,则 s[l- 1] 需要最小
2、维护前缀最小值
3、最后比较取最大值
2、代码
解法一:前缀和,熟悉前缀和解法
class Solution {public int maxSubArray(int[] nums) {// [-2,1,-3]// [0,-2,-1,-4]// [0,-2,-2,-4]int[] s = new int[nums.length + 1];int[] preMinSum = new int[nums.length + 1];s[0] = 0;preMinSum[0] = 0;for (int i = 1; i < s.length; i++) {s[i] = s[i - 1] + nums[i - 1];}for (int i = 1; i < s.length; i++) {preMinSum[i] = Math.min(preMinSum[i - 1], s[i]);}int result = -100000;for (int i = 1; i < s.length; i++) {result = Math.max(s[i] - preMinSum[i - 1],result);}return result;}
}
解法二:贪心