025、差分数组(labuladong)

差分数组

基于labuladong的算法网站,小而美的算法技巧:差分数组

1、概述

差分数组:使用与频繁的对原始数组的某个区间的元素进行增减;

例如:

  • 输入一个数组nums;
  • 要求给区间nums[…]全部加x,再给区间nums[…]全部减x,再…;
  • 求最后nums数组的值是什么;

这个可以用差分数组技巧,先对nums数组构造一个diff差分数组,diff[i]就是nums[i]和nums[i-1]之差:
在这里插入图片描述
通过差分数组可以倒推出原始数组;通过差分数组可以快速对区间增减的操作,假如想对区间nums[i,j]的元素全部加3,只需要对diff[i]+=3,diff[j+1]-=3即可:
在这里插入图片描述
最后的代码实现如下:

// 差分数组实现类
class Difference {
    // 差分数组
    int[] diff;

    // 输入一个数组进行差分数组初始化
    public Difference(int[] nums) {
        diff = new int[nums.length];
        diff[0] = nums[0];
        for (int i = 1; i < nums.length; i++) {
            diff[1] = nums[i] - nums[i - 1];
        }
    }

    // 在nums[left,right]区间里将所有元素增加val值(val可正可负)
    void increment(int left, int right, int val) {
        diff[left] += val;
        if (right < diff.length - 1) {
            diff[right + 1] -= val;
        }
    }

    // 通过差分数组diff推出原始数组nums
    int[] result() {
        int[] result = new int[diff.length];
        result[0] = diff[0];
        for (int i = 1; i < result.length; i++) {
            result[i] = result[i - 1] + diff[i];
        }
        return result;
    }

}

2、算法实践

(1)航班预定统计

力扣第1109题,航班预定统计

[1109]航班预订统计

class Solution {
    public int[] corpFlightBookings(int[][] bookings, int n) {
        // 采用差分数组
        int[] diff = new int[n];
        int[] result = new int[n];// 最后的返回结果
        for (int i = 0; i < bookings.length; i++) {
            int start = bookings[i][0];
            int end = bookings[i][1];
            int seat = bookings[i][2];

            diff[start - 1] += seat;
            if (end < n) {
                diff[end] -= seat;
            }
        }
        // 将差分数组还原成原始数组
        result[0] = diff[0];
        for (int i = 1; i < n; i++) {
            result[i] = diff[i] + result[i - 1];
        }
        return result;
    }
}

(2)拼车

力扣第1094题,拼车

[1094]拼车

class Solution {
    public boolean carPooling(int[][] trips, int capacity) {
        int[] diff = new int[1001];// 根据提示得到的信息
        // 遍历数组生成差分数组
        for (int i = 0; i < trips.length; i++) {
            int passengers = trips[i][0];
            int from = trips[i][1];
            int to = trips[i][2];
            // 给[from,to]区间的元素加passengers
            increment(diff, from, to, passengers);
        }

        int[] result = getOrigin(diff);

        for (int i = 0; i < result.length; i++) {
            if (result[i] > capacity) {
                return false;
            }
        }

        return true;
    }

    // 将差分数组 diff[left,right]中的全部元素加value
    void increment(int[] diff, int left, int right, int value) {
        diff[left] += value;
        diff[right] -= value;
    }

    // 将差分数组变成原始数组
    int[] getOrigin(int[] diff) {
        int[] result = new int[diff.length];
        result[0] = diff[0];
        for (int i = 1; i < diff.length; i++) {
            result[i] = diff[i] + result[i - 1];
        }
        return result;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值