前缀和
场景:原始数组不会被修改的情况下,频繁查询某个区间的累加和
class NumArray {
    private int[] preSum;
    public NumArray(int[] nums) {
        preSum = new int[nums.length+1];
        preSum[0] = 0;
        for(int i=1; i<preSum.length; i++) {
            preSum[i] = preSum[i-1] + nums[i-1];
        }
    }
    
    public int sumRange(int left, int right) {
        return preSum[right+1] - preSum[left];
    }
}
差分
场景:频繁对原始数组的某个区间的元素进行增减,然后求数组最后的形态
class Solution {
    public int[] corpFlightBookings(int[][] bookings, int n) {
        int[] nums = new int[n];
        Difference diff = new Difference(nums);
        for(int[] booking : bookings) {
            int i = booking[0] - 1;
            int j = booking[1] - 1;
            int v = booking[2];
            diff.increment(i, j, v);
        }
        return diff.result();
    }
}
class Difference {
    private int[] diff;
    public Difference(int[] nums) {
        diff = new int[nums.length];
        diff[0] = nums[0];
        for(int i=1; i<nums.length; i++) {
            diff[i] = nums[i] - nums[i-1];
        }
    }
    public void increment(int i, int j, int n) {
        diff[i] += n;
        if(j+1 < diff.length) {
            diff[j+1] -= n;
        }
    }
    public int[] result() {
        int[] result = new int[diff.length];
        result[0] = diff[0];
        for(int i=1; i<diff.length; i++) {
            result[i] = result[i-1] + diff[i];
        }
        return result;
    }
}
参考:
- https://labuladong.gitee.io/algo/2/20/24/
- https://labuladong.gitee.io/algo/2/20/25/