LeetCode第[56]题(Java):Merge Intervals

题目:合并区间

难度:Medium

题目内容

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]]

Example 2:

Input: [[1,4],[4,5]]
Output: [[1,5]]

我的思路:因为可能是乱序的,不好逐个比较,所以需要排序

1、将List内的元素进行排序(利用比较器),然后从前往后比较 ;

2、当前的end和后一个的start,看是否需要合并

3、如果需要合并则当前的end等于它自己与后一个的end中取大的,然后将后一个remove()掉

我的代码

 1 class Solution {
 2     public List<Interval> merge(List<Interval> intervals) {
 3         Collections.sort(intervals, new MyComparator());
 4
 5         for (int i = 0; i < intervals.size() - 1; i++) {
 6             if (intervals.get(i).end >= intervals.get(i+1).start) {
 7                 intervals.get(i).end = intervals.get(i).end > intervals.get(i+1).end ? intervals.get(i).end : intervals.get(i+1).end;
 8                 intervals.remove(i+1);
 9                 i--;
10             }
11         }
12         return intervals;
13     }
14 }
15
16 class MyComparator implements Comparator<Interval> {
17
18     public int compare(Interval one, Interval two) {
19         return one.start - two.start;
20     }
21
22 }  

我的复杂度:O(NlogN)    主要是排序的那里用了nlogn    剩下的只有n

编程过程中的问题

1、忘记比较器怎么实现:

方法一:将List中的类实现Comparable<E>接口(本题的E就是Interval),并重写compareTo方法(一个传入对象)  用自己的值和传入对象的值做比较即可。

【比较规则:自己比传入对象大就返回零,等于就等于0,小于就小于0,所以一般直接   return   自己 - 传入对象】如下:

    public int compareTo(Interval o) {
        return start - o.start;
    }

但是,本题的Interval是写死的不能在编辑中修改,但是不要急,还有另外一种办法:

  方法二:自己写一个类实现Comparator<E>接口,并重写compare方法(两个传入对象)

【比较规则:与上面类似  一般直接 return   前面一个对象 - 后面一个对象】如下:

    public int compare(Interval one, Interval two) {
        return one.start - two.start;
    }  

扩展:那如果要比较两个属性呢,比如先比较名字,再比较年龄————代码如下

    public int compare(Person one, Person two) {
        int i = one.name.compareTo(two.name); //比较名字字符串
        if (i == 0) { //如果名字一样,则继续比较年龄
            return one.age - two.age;
        } else { //首先比较名字,名字不一样,则返回比较结果
            return i;
        }
    } 

  使用此方法需要在sort()方法中传入作为第二个参数,(所以一般可直接在sort方法里使用匿名类)如下:

        Collections.sort(intervals, new Comparator<Interval>(){
            @Override
            public int compare(Interval interval1, Interval interval2){
                return interval1.start - interval2.start;
            }
        });

2、发现需要合并后,是不能直接将end取后一个的end的,因为后一个的end也是有可能比当前的小的,比如【【1,6】,【3,5】】,所以需要判断一下end的大小;

3、因为是顺序向后循环的,List调用remove方法去掉后一个之后,i 会指向后一个继续进行循环,但是此时应该仍然指向自己,继续判断后一个是否需要合并,所以需要 i - -。

  扩展:如果是从后往前循环的呢?需要 i ++?

    此时删去了下标i - 1,然后 i -- ,i 移到 下标 i -1 , 而此时的下标 i -1 就是remove之前的 下标 i 所以不再需要做操作。

    例如:下标 0,1,2  此时 i 等于2 ,将1remove(此时的下标2自动变为1),然后 i -- ,i还是指向原来的2的位置。

  所以,当在循环中调用List的remove方法的时候,一定要考虑下标的变化,而调整指针 i 的值。

答案代码

 1 class Solution {
 2     private class IntervalComparator implements Comparator<Interval> {
 3         @Override
 4         public int compare(Interval a, Interval b) {
 5             return a.start < b.start ? -1 : a.start == b.start ? 0 : 1;
 6         }
 7     }
 8
 9     public List<Interval> merge(List<Interval> intervals) {
10         Collections.sort(intervals, new IntervalComparator());
11
12         LinkedList<Interval> merged = new LinkedList<Interval>();
13         for (Interval interval : intervals) {
14             if (merged.isEmpty() || merged.getLast().end < interval.start) {
15                 merged.add(interval);
16             }
17             else {
18                 merged.getLast().end = Math.max(merged.getLast().end, interval.end);
19             }
20         }
21
22         return merged;
23     }
24 }

答案思路:和我的思路是一样的,先排序然后从头到位判断是否需要合并,

不过他使用了队列,空间复杂度提高了,但是这样避免了remove方法带来的多余的时间复杂度,二者各有好处。

原文地址:https://www.cnblogs.com/Xieyang-blog/p/9034145.html

时间: 2024-08-29 02:19:39

LeetCode第[56]题(Java):Merge Intervals的相关文章

[LeetCode][Java] Merge Intervals

题目: Given a collection of intervals, merge all overlapping intervals. For example, Given [1,3],[2,6],[8,10],[15,18], return [1,6],[8,10],[15,18]. 题意: 给定一组间隔的集合,合并所有的重复间隔. 比如, 给定[1,3],[2,6],[8,10],[15,18], 返回[1,6],[8,10],[15,18]. 算法分析: 参考博客http://www.

LeetCode第[88]题(Java):Merge Sorted Array(合并已排序数组)

题目:合并已排序数组 难度:Easy 题目内容: Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. 翻译: 给定两个排序的整数数组nums1和nums2,将nums2合并到nums1中作为一个排序数组. 注意: nums1和nums2中初始化的元素数量分别为m和n. nums1有足够的空间(大小大于或等于m+n)来容纳nums2中的额外元素. 我的思路:此处和归

lintcode 容易题:Merge Intervals 合并区间

题目: 合并区间 给出若干闭合区间,合并所有重叠的部分. 样例 给出的区间列表 => 合并后的区间列表: [ [ [1, 3], [1, 6], [2, 6], => [8, 10], [8, 10], [15, 18] [15, 18] ] ]挑战 O(n log n) 的时间和 O(1) 的额外空间. 解题: 先以区间的左边界进行排序,再异步的方式比较右边边界进行合并 程序来源 Java程序 /** * Definition of Interval: * public class Inte

LeetCode第[26]题(Java):Remove Duplicates from Sorted Array 标签:Array

题目难度:Easy 题目: Given a sorted array, remove the duplicates in-place such that each element appear only once and return the new length. Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extr

LeetCode第[5]题(Java):Longest Palindromic Substring 标签:String、动态规划

题目中文:求最长回文子串 题目难度:Medium 题目内容: Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000. 翻译: 给定一个字符串s,找出s中最长的回文子串.你可以假设s的最大长度是1000. 什么叫回文子串? 就是字符串中,满足能正读反读都一样的子串,就是回文子串.如下所示 Input: "babad"

LeetCode第[7]题(Java):Reverse Integer 标签:数学

题目:Reverse Integer 难度:Easy 题目内容: Given a 32-bit signed integer, reverse digits of an integer. Note:Assume we are dealing with an environment which could only hold integers within the 32-bit signed integer range. For the purpose of this problem, assum

LeetCode第[42]题(Java):Trapping Rain Water

题目:接雨水 难度:hard 题目内容: Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining. The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In

LeetCode第[79]题(Java):Word Search(矩阵单词搜索)

题目:矩阵单词搜索 难度:Medium 题目内容: Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same

LeetCode第[3]题(Java):Longest Substring Without Repeating Characters 标签:Linked List

题目中文:没有重复字符的最长子串 题目难度:Medium 题目内容: Given a string, find the length of the longest substring without repeating characters. Examples: Given "abcabcbb", the answer is "abc", which the length is 3. Given "bbbbb", the answer is &q