56. Merge Intervals的C++解法(重寫sort函式)
阿新 • • 發佈:2018-12-27
題目描述:https://leetcode.com/problems/merge-intervals/
挑戰中要求使用O(nlogn)的時間複雜度和O(1)的額外空間複雜度,所以使用了sort先對區間進行排序,然後在原容器上進行融合和刪除操作,注意有刪除操作之後i不需要自增了,後一個會自動移上來,如果無腦自增會跳過很多值。
但是這個方法比較慢。
class Solution { public: static bool cmp(const Interval &a, const Interval &b){ return (a.start<b.start); } vector<Interval> merge(vector<Interval> &intervals) { if (intervals.size()==0) return intervals; sort(intervals.begin(),intervals.end(),cmp); int head=intervals[0].start; int tail=intervals[0].end; int index=0; int i=1; while (i<intervals.size()) { if (intervals[i].start<=tail) if (intervals[i].end<=tail) intervals.erase(intervals.begin()+i); else { tail=intervals[i].end; intervals[index].end=tail; intervals.erase(intervals.begin()+i); } else { index=i; head=intervals[i].start; tail=intervals[i].end; i++; } } return intervals; } };
如果沒有這個限制,可以考慮用類似hash表的方法做,本來我是用了vector,之後看到一個很棒的方法用了map,好處在於:
1.由於不知道數字的範圍,不需要開很大的陣列
2.vector處理不了[0,0]這樣的情況,會判別為不存在,但是map即使是map[0],也會被計算在內。
class Solution { public: vector<Interval> merge(vector<Interval>& intervals) { map<int, int> terminals; for (auto& i : intervals){ terminals[i.start] += 1; terminals[i.end] -= 1; } vector<Interval> res; int levels = 0, start; for (auto& p : terminals){ //map是預設以key值排序的 int num = p.first, cnt = p.second; if (levels == 0)//第一次碰上0是一個區間的開始 start = num; levels += cnt; if (levels == 0){//再一次碰上0是區間的結束 res.push_back(Interval(start, num)); } } return res; } };