算法练习:前缀和数组、差分数组

2022/09/14 Algorithm 共 1066 字,约 4 分钟

前缀和

场景:原始数组不会被修改的情况下,频繁查询某个区间的累加和

力扣 303. 区域和检索 - 数组不可变

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];
    }
}

差分

场景:频繁对原始数组的某个区间的元素进行增减,然后求数组最后的形态

力扣 1109. 航班预订统计

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/

Search

    Table of Contents