LeetCode 1109. 航班预订统计

题目链接:

力扣https://leetcode-cn.com/problems/corporate-flight-bookings/

【分析】这是一道典型的差分数组的应用,何为差分数组呢,下面看一个例子。

下标 i01234
原始值 arrs35269
差分 diffs32-343

差分数组的第一个设置为arrs[0],i从1开始,第i个位置为arrs[i] - arrs[i - 1],即当前值和前一个值的差。那么通过差分数组如何还原原始数组呢。首先数组第一个org[0]=diffs[0],后面第i个原始值就是对差分数组求前缀和即可,则org[1] = 3 + 2 = 5, org[2] = 5 - 3 = 2, org[3] = 2 + 4 = 6 ...

如果对原数组进行修改,那么如何体现在差分数组上呢,例如我将下标[1,3]的值+5,那么只需要将diffs[1]+5, diffs[3 + 1] - 5即可,也就是在前端点加,在后端点减。需要特别注意后面数组越界的问题,其实后端点为边界时,无需再将边界外减一个值了,因为我们无需计算边界外数组的值。

class Solution {
    public int[] corpFlightBookings(int[][] bookings, int n) { 
        int[] arrs = new int[n + 1];
        int i, m = bookings.length;
        for(i = 0; i < m; i++){
            arrs[bookings[i][0] - 1] += bookings[i][2];
            arrs[bookings[i][1]] -= bookings[i][2];
        }
        int[] ans = new int[n];
        ans[0] = arrs[0];
        for(i = 1; i < n; i++){
            arrs[i] += arrs[i - 1];
            ans[i] = arrs[i];
        }
        return ans;
    }
}

【树状数组】对于这种区间修改,单点查询。我们知道,树状数组也是能做的,只是此时树状数组中维护的是一个差分数组。这道题在初始化的时候tree全部都是0,随着预订,往树状数组中存值。

class Solution {
    int[] tree;
    int n;
    int lowbit(int x){
        return x & -x;
    }
    void add(int x, int val){
        for(; x <= n; x += lowbit(x)) tree[x] += val;
    }
    int ask(int x){
        int ans = 0;
        for(; x > 0; x -= lowbit(x)) ans += tree[x];
        return ans;
    }

    public int[] corpFlightBookings(int[][] bookings, int n) {
        this.n = n;
        int[] ans = new int[n];
        tree = new int[n + 1];
        int m = bookings.length;
        int i, j;
        for(i = 0; i < m; i++){
            add(bookings[i][0], bookings[i][2]);
            add(bookings[i][1] + 1, -bookings[i][2]);
        }
        for(i = 1; i <= n; i++){
            ans[i - 1] = ask(i);
        }
        return ans;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值