leetcode算法12-合并区间

题目:

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。

示例 1:

输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].

示例 2:

输入:intervals = [[1,4],[4,5]]
输出:[[1,5]]
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。

代码:

class Solution {
    public int[][] merge(int[][] intervals) {
        //思路:数组按照左端点排序,比较后一个左端点是否小于上一个的右端点,
        //如果小于,可以合并。
        // 由于我们已经按照左端点排序,所以后一个的左端点必然大于等于合并区间的左端点,
        // 所以无需更新当前合并区间的左端点。

        //构建结果集
        List<int[]> ans = new ArrayList<>();

        //排序:仅对左端点排序
        Arrays.sort(intervals, (p, q) -> p[0] - q[0]);//p,q是数组
        //完整写法
        /**        Arrays.sort(intervals, new Comparator<int[]>() {
            public int compare(int[] interval1, int[] interval2) {
                return interval1[0] - interval2[0];
            }
        });
        */

        for (int[] nums : intervals) {
            //比较后一个的左端点,注意从第二个开始
            int length = ans.size();
            if (length > 0 && nums[0] <= ans.get(length - 1)[1]) {
                // 后一个左端点小于前一个右端点;可以合并。
                //只需更新右端点的值(右端点是两个钟比较大的那个),左端点,不管
                ans.get(length - 1)[1] = Math.max(nums[1], ans.get(length - 1)[1]);
            } else {
                //不可以合并直接加入
                ans.add(nums);
            }
        }
        return ans.toArray(new int[ans.size()][]);

    }
}

关键点:

1.思路:数组按照左端点排序,比较后一个左端点是否小于上一个的右端点,如果小于,可以合并(只需更新右端点的值(右端点是两个中比较大的那个))。由于我们已经按照左端点排序,所以后一个的左端点必然大于等于合并区间的左端点,所以无需更新当前合并区间的左端点。

2.二维数组排序,Arrays.sort()重写规则,使用函数式接口,lambda表达式简写,只对数字左端排序。

排序代码详解:

Arrays.sort(intervals, new Comparator<int[]>() {
            public int compare(int[] interval1, int[] interval2) {
                return interval1[0] - interval2[0];
            }
        });
1. Arrays.sort

Arrays.sort 是 Java 中用于对数组进行排序的方法。它可以对一维数组进行自然排序(升序),也可以通过提供一个自定义的比较器来对数组进行自定义排序。

2. Comparator<int[]>

Comparator 是一个接口,用于定义对象之间的比较规则。在这个例子中,Comparator<int[]> 表示比较的是 int[] 类型的对象(即二维数组中的每个子数组)。

3. compare 方法

compare 方法是 Comparator 接口中的一个方法,用于比较两个对象。在这个例子中,它比较的是两个子数组 interval1interval2

  • 参数

    • interval1interval2int[] 类型的数组。

  • 返回值

    • 如果 interval1[0] < interval2[0],返回负数。

    • 如果 interval1[0] == interval2[0],返回 0。

    • 如果 interval1[0] > interval2[0],返回正数。

这种返回值的设计使得 Arrays.sort 可以根据这些值来决定数组的排序顺序。

4. 排序规则

在这段代码中,排序规则是根据每个子数组的第一个元素(interval1[0]interval2[0])进行升序排序。具体来说:

  • interval1[0] - interval2[0]

    • 如果 interval1[0] 小于 interval2[0],返回负数,表示 interval1 应该排在 interval2 之前。

    • 如果 interval1[0] 等于 interval2[0],返回 0,表示它们的顺序可以互换。

    • 如果 interval1[0] 大于 interval2[0],返回正数,表示 interval1 应该排在 interval2 之后。

原理

Lambda 表达式的核心是 函数式接口。函数式接口是 Java 中一种特殊的接口,它只有一个抽象方法。Comparator 就是一个典型的函数式接口,因为它只有一个抽象方法 compare

当使用 Lambda 表达式时,Java 编译器会自动将 Lambda 表达式转换为对应的函数式接口的实现类。具体来说:

  1. 类型推断

    • 编译器会根据上下文推断 Lambda 表达式的参数类型。在你的例子中,interval1interval2 的类型被推断为 int[],因为 Arrays.sort 的第二个参数是一个 Comparator<int[]>

  2. 匿名类的实现

    • 编译器会生成一个匿名类,实现 Comparator 接口,并将 Lambda 表达式中的逻辑转换为 compare 方法的实现。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值