Merge K Sorted Interval Lists

Merge K sorted interval lists into one sorted interval list. You need to merge overlapping intervals too.

Example

Example1

Input: [
  [(1,3),(4,7),(6,8)],
  [(1,2),(9,10)]
]
Output: [(1,3),(4,8),(9,10)]

Example2

Input: [
  [(1,2),(5,6)],
  [(3,4),(7,8)]
]
Output: [(1,2),(3,4),(5,6),(7,8)]

思路:这个题目跟 Merge K sorted List 一样;知道了怎么merge两个interval Merge Two Sorted Interval Lists,现在要merge K,那么就divide and conquer,劈成两半,跟merge sort一样;

/**
 * Definition of Interval:
 * public classs Interval {
 *     int start, end;
 *     Interval(int start, int end) {
 *         this.start = start;
 *         this.end = end;
 *     }
 * }
 */

public class Solution {
    /**
     * @param intervals: the given k sorted interval lists
     * @return:  the new sorted interval list
     */
    public List<Interval> mergeKSortedIntervalLists(List<List<Interval>> intervals) {
        List<Interval> list = new ArrayList<Interval>();
        if(intervals == null || intervals.size() == 0) return list;
        return mergeKInterval(intervals, list, 0, intervals.size()-1);
    }
    
    private List<Interval> mergeKInterval(List<List<Interval>> intervals,
                                        List<Interval> list,
                                        int start, int end) {
        if(start == end) {
            return intervals.get(start);
        }   
        int mid = start + (end - start) / 2;
        List<Interval> leftInterval = mergeKInterval(intervals, list, start, mid);
        List<Interval> rightInterval = mergeKInterval(intervals, list, mid+1, end);
        return mergeTwoInterval(leftInterval, rightInterval);
    }
    
    public List<Interval> mergeTwoInterval(List<Interval> list1, List<Interval> list2) {
        List<Interval> list = new ArrayList<Interval>();
        if(list1 == null || list1.size() == 0) return list2;
        if(list2 == null || list2.size() == 0) return list1;
        
        
        List<Interval> templist = new ArrayList<Interval>();
        int i = 0; int j = 0;
        while(i < list1.size() && j < list2.size()){
            Interval a = list1.get(i);
            Interval b = list2.get(j);
            if(a.start < b.start){
                templist.add(a);
                i++;
            } else {
                templist.add(b);
                j++;
            }
        }
        
        while(i < list1.size()){
            templist.add(list1.get(i));
            i++;
        }
        
        while(j < list2.size()){
            templist.add(list2.get(j));
            j++;
        }
        
        return mergeInterveral(templist);
    }
    
    private List<Interval> mergeInterveral(List<Interval> list) {
        List<Interval> res = new ArrayList<Interval>();
        Interval cur = list.get(0);
        for(int i = 1; i < list.size(); i++){
            Interval next = list.get(i);
            if(cur.end >= next.start){
                cur = new Interval(cur.start, Math.max(cur.end, next.end));
            } else {
                // cur.end < next.start;
                res.add(cur);
                cur = next;
            }
        }
        res.add(cur);
        return res;
    }
}

思路2:两两merge,然后输出最后一个;

/**
 * Definition of Interval:
 * public classs Interval {
 *     int start, end;
 *     Interval(int start, int end) {
 *         this.start = start;
 *         this.end = end;
 *     }
 * }
 */

public class Solution {
    /**
     * @param intervals: the given k sorted interval lists
     * @return:  the new sorted interval list
     */
    public List<Interval> mergeKSortedIntervalLists(List<List<Interval>> intervals) {
        if(intervals == null || intervals.size() == 0) return null;
        
        while(intervals.size() > 1){
            List<List<Interval>> lists = new ArrayList<List<Interval>>();
            for(int i = 0; i+1 < intervals.size(); i+=2){
                List<Interval> newlist = mergeTwoInterval(intervals.get(i), intervals.get(i+1));
                lists.add(newlist);
            }
            if(intervals.size() % 2 == 1){
                lists.add(intervals.get(intervals.size() -1 ));
            }
            intervals = lists;
        }
        return intervals.get(0);
    }
    
    public List<Interval> mergeTwoInterval(List<Interval> list1, List<Interval> list2) {
        List<Interval> list = new ArrayList<Interval>();
        if(list1 == null || list1.size() == 0) return list2;
        if(list2 == null || list2.size() == 0) return list1;
        
        
        List<Interval> templist = new ArrayList<Interval>();
        int i = 0; int j = 0;
        while(i < list1.size() && j < list2.size()){
            Interval a = list1.get(i);
            Interval b = list2.get(j);
            if(a.start < b.start){
                templist.add(a);
                i++;
            } else {
                templist.add(b);
                j++;
            }
        }
        
        while(i < list1.size()){
            templist.add(list1.get(i));
            i++;
        }
        
        while(j < list2.size()){
            templist.add(list2.get(j));
            j++;
        }
        
        return mergeInterveral(templist);
    }
    
    private List<Interval> mergeInterveral(List<Interval> list) {
        List<Interval> res = new ArrayList<Interval>();
        Interval cur = list.get(0);
        for(int i = 1; i < list.size(); i++){
            Interval next = list.get(i);
            if(cur.end >= next.start){
                cur = new Interval(cur.start, Math.max(cur.end, next.end));
            } else {
                // cur.end < next.start;
                res.add(cur);
                cur = next;
            }
        }
        res.add(cur);
        return res;
    }
}

思路3:写成priorityqueue版本。

/**
 * Definition of Interval:
 * public classs Interval {
 *     int start, end;
 *     Interval(int start, int end) {
 *         this.start = start;
 *         this.end = end;
 *     }
 * }
 */

public class Solution {
    /**
     * @param intervals: the given k sorted interval lists
     * @return:  the new sorted interval list
     */
     
    private class Node {
        int x;
        int y;
        Interval interval;
        public Node(int x, int y, Interval interval) {
            this.x = x;
            this.y = y;
            this.interval = interval;
        }
    }
    
    private class myComparator implements Comparator<Node> {
        @Override
        public int compare(Node a, Node b) {
            return (a.interval.start - b.interval.start);
        }
    }

    public List<Interval> mergeKSortedIntervalLists(List<List<Interval>> intervals) {
        if(intervals == null || intervals.size() == 0) return null;
        int k = intervals.size();
        PriorityQueue<Node> pq = new PriorityQueue<Node>(k, new myComparator());
        
        for(int i = 0; i < k; i++){
            if(intervals.get(i) != null && intervals.get(i).size() > 0){
                pq.add(new Node(i, 0, intervals.get(i).get(0)));
            }
        }
        
        List<Interval> result = new ArrayList<Interval>();
        Node cur = null;
        while(!pq.isEmpty()){
            Node next = pq.poll();
            if(cur == null){
                cur = next;
            } else {
                // compare cur and next; merge if needed;
                if(cur.interval.end < next.interval.start) {
                    result.add(cur.interval);
                    cur = next;
                } else {
                    // cur.end >= next.start;
                    Interval newInterval = new Interval(cur.interval.start, Math.max(cur.interval.end, next.interval.end));
                    cur = new Node(cur.x, cur.y, newInterval);
                }
            }
            // add next.next node;
            if(next.y + 1 < intervals.get(next.x).size()){
                pq.add(new Node(next.x, next.y+1, intervals.get(next.x).get(next.y+1)));
            }
        }
        if(cur != null) {
            result.add(cur.interval);
        }
        return result;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值