Leetcode - Merge Intervals

Given a collection of intervals, merge all overlapping intervals.

[分析] 这题思路不难,将输入的区间数组按左边界排序然后合并。但是调试了很久,收获是熟悉了些Java语法。首先,忘记对ArrayList排序可以使用Collections.sort(),不厌其烦地在ArrayList和数组间转换为了能使用Arrays.sort进行排序;然后使用Iterator对Arrays.asList()转化得到的ArrayList进行删除操作时遭遇了java.lang.UnsupportedOperationException, Google上查了一番并查看相应实现知道通过Arrays.asList()获取到的List并不支持add和remove等修改操作,该List对象是在Arrays中实现的一个内部类ArrayList,继承AbstractList且没有重载AbstractList的add 和remove方法。一番修改后又撞上了java.lang.IllegalArgumentException: Comparison method violates its general contract!说我的Comparator实现得不对,不满足比较的基本性质,一查发现是有个手误。不断优化得到三个版本。

public class Solution {
    Comparator<Interval> comparator = new Comparator<Interval>() {
        public int compare(Interval a, Interval b) {
            return a.start - b.start;
        }
    };
    
    // Method 3: merge结果存储在额外List中, Method 2 的代码优化版
    public List<Interval> merge(List<Interval> intervals) {
        if (intervals == null || intervals.size() <= 1)
            return intervals;
        Collections.sort(intervals, comparator);
        List<Interval> result = new ArrayList<Interval>();
        int i = 0, N = intervals.size();
        while (i < N) {
            result.add(intervals.get(i++));
            Interval last = result.get(result.size() - 1);
            while (i < N && intervals.get(i).start <= last.end) {
                last.end = Math.max(last.end, intervals.get(i++).end);
            }
        }
        return result;
    }
    
    // Method 2: merge结果存储在额外List中
    public List<Interval> merge2(List<Interval> intervals) {
        if (intervals == null || intervals.size() <= 1)
            return intervals;
        Collections.sort(intervals, comparator);
        List<Interval> result = new ArrayList<Interval>();
        result.add(intervals.get(0));
        int i = 1;
        while (i < intervals.size()) {
            int currEnd = result.get(result.size() - 1).end;
            while (i < intervals.size() && currEnd >= intervals.get(i).end) {
                i++;
            }
            if (i == intervals.size()) break;
            if (intervals.get(i).start > currEnd)
                result.add(intervals.get(i));
            else
                result.get(result.size() - 1).end = intervals.get(i).end;
            i++;
        }
        return result;
    }
    
    // Method 1: 在原数组中merge
    public List<Interval> merge(List<Interval> intervals) {
        if (intervals == null || intervals.size() < 2)
            return intervals;
        Collections.sort(intervals, comparator);
        int i = 0;
        while (i < intervals.size() - 1) {
            Interval curr = intervals.get(i);
            Interval next = intervals.get(i + 1);
            if (curr.end >= next.start) {
                curr.end = Math.max(curr.end, next.end);
                intervals.remove(i + 1);
            } else {
                i++;
            }
        }
        return intervals;
    }
}

猜你喜欢

转载自likesky3.iteye.com/blog/2226614