前缀和:数组nums[]的第0项到当前项的和,用数组prefixSum表示的话,x为当前项,则有:
prefixSum[x]=nums[0]+nums[1]+…+nums[x]
从前缀和可以推出:
nums 的某项 = 两个相邻前缀和的差:
nums[x] = prefixSum[x] - prefixSum[x - 1]
nums 的 第 i 到 j 项 的和,有:
nums[i] +…+nums[j]=prefixSum[j] - prefixSum[i - 1]
当 i 为 0,此时 i-1 为 -1,我们故意让 prefixSum[-1] 为 0,使得通式在i=0时也成立:
nums[0] +…+nums[j]=prefixSum[j]
一、和为K的子数组,LC560

class Solution {public int subarraySum(int[] nums, int k) {int size = nums.length;//前缀和int[] prefixSum = new int[size+1];prefixSum[0] = 0;prefixSum[1] = nums[0];for (int i=1; i<size; i++) {prefixSum[i+1] = nums[i] + prefixSum[i];}int cnt = 0;for (int i=0; i<=size; i++) {for (int j=i+1; j<=size; j++) {if (prefixSum[j] - prefixSum[i] == k) {cnt++;}}}return cnt;}}class Solution {public int subarraySum(int[] nums, int k) {//前缀和+HashMap//记录前缀和-k出现的次数就行Map<Integer, Integer> map = new HashMap<>();//自身也可以满足map.put(0, 1);int size = nums.length;int prefixNum = 0;int cnt = 0;for (int i=0; i<size; i++) {prefixNum += nums[i];if (map.containsKey(prefixNum - k)) {cnt += map.get(prefixNum-k);}map.put(prefixNum, map.getOrDefault(prefixNum, 0)+1); //记录每个前缀和}return cnt;}}
二、统计【优美子数组】
三、连续数组,LC525

class Solution {public int findMaxLength(int[] nums) {int size = nums.length;int res = 0;//前缀和 下标Map<Integer, Integer> map = new HashMap<>();map.put(0, -1);int preSum = 0;for (int i=0; i<size; i++) {if (nums[i] == 1) {preSum++;} else {preSum--;}if (map.containsKey(preSum)) {int index = map.get(preSum);res = Math.max(res, i - index);} else {map.put(preSum, i);}}return res;}//超时// public int findMaxLength(int[] nums) {// int size = nums.length;// //前缀和// int[] preSum = new int[size+1];// preSum[0] = 0;// for (int i=0; i<size; i++) {// if (nums[i] == 0) {// nums[i] = -1;// }// preSum[i+1] = nums[i] + preSum[i];// }// int res = 0;// for (int i=0; i<=size; i++) {// for (int j=i; j<=size; j++) {// if (preSum[i] - preSum[j] == 0) {// res = Math.max(res, j-i);// }// }// }// return res;// }}
