#156 Merge Intervals

题目描述:

Given a collection of intervals, merge all overlapping intervals.

Example

Given intervals => merged intervals:

[                     [
  [1, 3],               [1, 6],
  [2, 6],      =>       [8, 10],
  [8, 10],              [15, 18]
  [15, 18]            ]
]
Challenge 

O(n log n) time and O(1) extra space.

题目思路:

看了jiuzhang的解法,觉得特别简洁,但是对我理解有点绕。我的想法code比较啰嗦,可能更好理解一些,以[[4,5],[2,4],[4,6],[3,4],[0,0],[1,1],[3,5],[2,2]]举例:

1. 首先我想把start和end混在一起排序,那怎么区分这个点是start和end呢?用符号区分,build一个map(因为map的key是排序的),把start/end当作key,val为key出现的次数。比如,例子中的数字在map中出现的情况为-- 0:0,1:0,2:1,3:2,4:0,5:-2,6:-1,这里的0不代表没有出现,而是indicate了这个点既是start也是end(出现了两次,或者4次,etc)。

2. map有了之后,我建一个stack,这个stack专门存放start点。

3. 把map中的key一个一个拿出来,如果是start就丢进stack中(出现了几次就丢几个),如果是end就pop一次stack。如果pop完发现stack是空的,就把最后一次pop出来的start和当前的end组成一个inverval。

这个解法不是最优,也有挺多空间cost,不过我觉得对我来说比较容易理解些。

Mycode(AC = 73ms):

/**
 * Definition of Interval:
 * classs Interval {
 *     int start, end;
 *     Interval(int start, int end) {
 *         this->start = start;
 *         this->end = end;
 *     }
 */
class Solution {
public:
    /**
     * @param intervals: interval list.
     * @return: A new interval list.
     */
    vector<Interval> merge(vector<Interval> &intervals) {
        // write your code here
        map<int, int> sorted_interv;
        vector<Interval> ans;
        
        // 1,2,3,6
        // build the map with start: positive numbers;
        // end: negative numbers
        for (int i = 0; i < intervals.size(); i++) {
            int start = intervals[i].start;
            int end = intervals[i].end;
            
            insertMap(sorted_interv, start, 1);
            insertMap(sorted_interv, end, -1);
        }
        
        stack<int> helper;
        for (auto it = sorted_interv.begin(); it != sorted_interv.end(); it++) {
            int key = it->first;
            int val = it->second;
            
            // if is starting point, then push into 
            // stack
            while (sorted_interv[key] >= 0) {
                helper.push(key);
                
                if (sorted_interv[key] == 0) {
                    sorted_interv[key] = -1;
                    break;
                }
                else {
                    sorted_interv[key] -= 1;
                }
            }
            
            // if is ending point, then pop the stack,
            // if stack is empty, then is new interval, 
            // write into answer
            while (sorted_interv[key] < 0 && !helper.empty()) {
                int top = helper.top();
                helper.pop();
                
                if (helper.empty()) {
                    ans.push_back({top, key});
                }
                
                if (sorted_interv[key] <= -1) {
                    sorted_interv[key] += 1;
                }
            }
        }
        
        return ans;
    }
    
    // insert the start/end point into map
    void insertMap(map<int, int>& sorted_interv, int point, int i) {
        if (sorted_interv.find(point) != sorted_interv.end()) {
            sorted_interv[point] += i;
        }
        else {
            sorted_interv[point] = i;
        }
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值