LeetCode 56. Merge Intervals 合并区间(Java)

题目:

Given a collection of intervals, merge all overlapping intervals.

Example 1:
Input: [[1,3],[2,6],[8,10],[15,18]]
Output: [[1,6],[8,10],[15,18]]
Explanation: Since intervals [1,3] and [2,6] overlaps, merge them into [1,6].

Example 2:
Input: [[1,4],[4,5]]
Output: [[1,5]]
Explanation: Intervals [1,4] and [4,5] are considered overlapping.

NOTE: input types have been changed on April 15, 2019. Please reset to default code definition to get new method signature.

解答:

本题参考了很多他人的答案,值得学习。
解题思路如下:

  1. 将给定的集合,根据每个区间的起始点,按照从大到小的顺序进行排序。其中通过采用匿名内部类,重写了 Comparator 接口中的 compare 方法,对数组进行了自定义排序
  2. 遍历排序后的集合进行合并,若位置 i 的右区间 > 位置 i+1 的左区间,则说明有重合需要合并,取右区间值 = Math.max(end, intervals[i+1][1])。不能合并的则直接 add
  3. 将最终结果的 ArrayList 通过 toArray() 方法转换为二维数组形式并返回
class Solution {
    public int[][] merge(int[][] intervals) {
        Arrays.sort(intervals, new Comparator<int[]>() {
            @Override
            public int compare(int[] a1, int[] a2) {
                return a1[0]-a2[0];
            }
        });
        List<int []> res = new ArrayList<>();
        for(int i=0; i<intervals.length; i++) {
            int start = intervals[i][0];
            int end = intervals[i][1];
            while(i<intervals.length-1 && end>=intervals[i+1][0]) {
                end = Math.max(end, intervals[i+1][1]);
                i++;
            }
            res.add(new int[] {start, end});
        }
        return res.toArray(new int[res.size()][2]);
    }
}
补充:

Arrays.sort() 方法
本题中通过采用匿名内部类重写 Comparator 接口中的 compare 方法,对数组进行了自定义的排序。分析 Arrays.sort() 源码可以看到:

     * @param <T> the class of the objects to be sorted
     * @param a the array to be sorted
     * @param c the comparator to determine the order of the array.  A
     *        {@code null} value indicates that the elements'
     *        {@linkplain Comparable natural ordering} should be used.
     * @throws ClassCastException if the array contains elements that are
     *         not <i>mutually comparable</i> using the specified comparator
     * @throws IllegalArgumentException (optional) if the comparator is
     *         found to violate the {@link Comparator} contract
     */
    public static <T> void sort(T[] a, Comparator<? super T> c) {
        if (c == null) {
            sort(a);
        } else {
            // Android-changed: LegacyMergeSort is no longer supported
            // if (LegacyMergeSort.userRequested)
            //     legacyMergeSort(a, c);
            // else
                TimSort.sort(a, 0, a.length, c, null, 0, 0);
        }
    }

通常,Arrays.sort(T[] a, Comparator<? Super T> c)用 Comparator 接口可以实现自定义排序规则。比如实现降序排列:

import java.util.*;

public class Main {
    public static void main(String[] args){
        Integer[] arr = {5,4,7,9,2,12,54,21,1};
        //降序
        Arrays.sort(arr, new Comparator<Integer>() {
            public int compare(Integer a, Integer b) {
                return b-a;
            }
        });
        System.out.println(Arrays.toString(arr));	//[54, 21, 12, 9, 7, 5, 4, 2, 1]
    }   
}

这里有一篇博文,介绍了 Arrays.sort() 方法:深入理解Arrays.sort() ,其中我们也可以学习到,Arrays.sort() 的源码实现为两枢轴快速排序
这里附一个匿名内部类的简要讲解:匿名内部类

ArrayList 转换为数组
ArrayList 可采用 toArray() 方法将List转为数组。toArray() 有两个重载形式:

  • list.toArray();:将 list 直接转为 Object[] 数组
  • list.toArray(T[] a);:将 list 转化为所需要类型的数组,即会转化为与 list 内容相同的类型

如果需要类型转换,不能采用将list 直接强制类型转换,如错误写法:

ArrayList<String> list=new ArrayList<String>();
for (int i = 0; i < 4; i++) {
    list.add(""+i);
} 
String[] array= (String[]) list.toArray();	//报错

注意:不能将Object[] 转化为String[]。java中的强制类型转换只能针对单个对象,不能将数组整个强制类型转换,需要单个元素遍历并转换类型

Object[] arr = list.toArray();
for (int i = 0; i < arr.length; i++) {
    String e = (String) arr[i];
    System.out.println(e);
}

这样的过程显得过于繁琐。所以我们通常采用list.toArray(T[] a);进行集合转为数组的操作

String[] array =new String[list.size()];
list.toArray(array);

附一个详解链接:深入理解List的toArray()方法和toArray(T[] a)方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值