【数据结构与算法 | 第六篇】力扣1109,1094差分数组

他跟我们前一次学过的前缀数组有些类似,都是通过new一个数组,对他进行操作,得到我们想要的

差分数组的主要适用场景是频繁对原始数组的某个区间的元素进行增减。

复制代码
// 差分数组工具类
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];
        }
    }

    // 给闭区间 [i, j] 增加 val(可以是负数)
    public void increment(int i, int j, int val) {
        diff[i] += val;
        if (j + 1 < diff.length) {
            diff[j + 1] -= val;
        }
    }

    // 返回结果数组
    public int[] result() {
        int[] res = new int[diff.length];
        // 根据差分数组构造结果数组
        res[0] = diff[0];
        for (int i = 1; i < diff.length; i++) {
            res[i] = res[i - 1] + diff[i];
        }
        return res;
    }
}

力扣第 1109 题「航班预订统计」:

复制代码
class Solution {
    public int[] corpFlightBookings(int[][] bookings, int n) {
        // nums 初始化为全 0
        int[] nums = new int[n];
        // 构造差分解法
        Difference df = new Difference(nums);

        for (int[] booking : bookings) {
            // 注意转成数组索引要减一哦,因为航班对应的是1,2,3,换到索引要-1对齐
            int i = booking[0] - 1;
            int j = booking[1] - 1;
            int val = booking[2];
            // 对区间 nums[i..j] 增加 val
            df.increment(i, j, val);
        }
        // 返回最终的结果数组
        return df.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];
            }
        }

        // 给闭区间 [i, j] 增加 val(可以是负数)
        public void increment(int i, int j, int val) {
            diff[i] += val;
            if (j + 1 < diff.length) {
                diff[j + 1] -= val;
            }
        }

        public int[] result() {
            int[] res = new int[diff.length];
            // 根据差分数组构造结果数组
            res[0] = diff[0];
            for (int i = 1; i < diff.length; i++) {
                res[i] = res[i - 1] + diff[i];
            }
            return res;
        }
    }

}

乍一看挺长的代码,其实写起来也并不简单.

我认为我们把他分段理解来写会比较好一点:

1.先构建原数组

2.new差分数组--原数组当前-前一个

3.把要加的用for抽离出来,注意是否要-1(情景)

4.把抽离出来的各个数,给差分数组进行运算(死的)

5.new一个结果数组,存放差分数组运算完完后的内容.

力扣第 1094 题「拼车」

复制代码
class Solution {
    public boolean carPooling(int[][] trips, int capacity) {
        // 最多有 1000 个车站
        int[] nums = new int[1001];
        // 构造差分解法
        Difference df = new Difference(nums);

        for (int[] trip : trips) {
            // 乘客数量
            int val = trip[0];
            // 第 trip[1] 站乘客上车
            int i = trip[1];
            // 第 trip[2] 站乘客已经下车,
            // 即乘客在车上的区间是 [trip[1], trip[2] - 1]
            int j = trip[2] - 1;
            // 进行区间操作
            df.increment(i, j, val);
        }

        int[] res = df.result();

        // 客车自始至终都不应该超载
        for (int i = 0; i < res.length; i++) {
            if (capacity < res[i]) {
                return false;
            }
        }
        return true;
    }

    // 差分数组工具类
    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];
            }
        }

        // 给闭区间 [i, j] 增加 val(可以是负数)
        public void increment(int i, int j, int val) {
            diff[i] += val;
            if (j + 1 < diff.length) {
                diff[j + 1] -= val;
            }
        }

        // 返回结果数组
        public int[] result() {
            int[] res = new int[diff.length];
            // 根据差分数组构造结果数组
            res[0] = diff[0];
            for (int i = 1; i < diff.length; i++) {
                res[i] = res[i - 1] + diff[i];
            }
            return res;
        }
    }

}

这道题的步骤跟前面一样,我提几个要注意的步骤:

1.乘客下车在5,所以他只是1-4在车上

2.最后得到结果数组要进行for循环的遍历判断

相关推荐
Dovis(誓平步青云)1 小时前
总用电下降了,为什么家庭能源看板仍然提示异常
java·开发语言·数据库·人工智能·算法·电脑·能源
程序猿乐锅1 小时前
【从0-1学习Python | 第四篇】Python 字符串和元组
java·开发语言·笔记·后端·python·学习
开开心心就好1 小时前
Windows视频播放器推荐,精简版体积更小
java·服务器·开发语言·eclipse·pdf·ocr·音视频
开开心心就好1 小时前
A3的PDF怎么切成A4?拖一下分割线就行
服务器·开发语言·python·算法·pdf·ocr·tornado
Rain的Java大神之路1 小时前
10 万人抢 2000 个座位,电影票选座系统怎么防超卖?一文讲透大厂高频场景题
java·后端·面试
闻缺陷则喜何志丹1 小时前
详细设计说明书的内容要求
算法·测试·存储
砚底藏山河1 小时前
量化新手误区:因子计算与行情数据的工程化解耦
java·数据库·python·金融
和裕2 小时前
定制纸箱刀卡、平卡、隔档分别是什么?结构与适用场景区别全解析
大数据·运维·网络·人工智能·算法
威哥爱编程2 小时前
【AI全栈12-07】Spring Boot 用 Agent 自动完成多步运营任务
java·spring boot·后端
未秃头的程序猿2 小时前
我用 Spring AI + MCP 把公司内部系统接给了 AI,过程没想象中顺利
java·后端