前前綴和是一種重要的預處理,能大大降低查詢的時間複雜度。
引入差分
差分:表示當前數字與上一個數字的差值
差分數組即是講這一系列差分值放入一個數組。
舉個例子,定義數組a爲
int a[10]={0,2,4,5,6,10,3,7,8,9};
那麼差分數組dif的值爲
2 2 1 1 4 -7 4 1 1
前綴和
前綴和,即利用一個數組sum來記錄數組a前i項的和。
可用來求區間和,如求數組a在區間[L,R]的和,那麼就是將a[L] 和 a[R] 之間的所有的數相加,但是如果提前知道前L項的和sum[L] 以及前R項的和 sum[R],那麼所求的結果就是 sum[L] - sum[R]。這裏sum[L] 以及sum[R] 就是前綴和。(leetcode的560題)
利用前綴和可以極大的降低區間查詢的時間複雜度
LeetCode相關題目
560. 和爲K的子數組
題目目標是:找到該數組中和爲 k 的連續的子數組的個數
那麼重點就是找到和爲k的連續子數組
假設在區間[left, right]中的數組元素的和爲k,那麼利用前綴和中的sum數組,即sum[right] - sum[left] = k,然後掃描整個數組,利用map存儲 sum[left] 出現的個數,加上sum[right]-k作爲出現過的前n項和的個數,然後更新統計量即可。
class Solution {
public:
//本題中不需要把sum的值存到數組中,只需要用map計算出現次數即可
int subarraySum(vector<int>& nums, int k) {
int res = 0;
int sum = 0;
//在map中初始化一對鍵值對{0,1}
unordered_map<int,int> mp{{0,1}};
for(int i = 0; i <nums.size();++i){
//更新當前sum[right]
sum += nums[i];
//更新統計量,sum-k即爲sum[left]
res += mp[sum - k];
//統計sum出現次數
mp[sum]++;
}
return res;
}
};