这道题有很多解法。
我的解法参考了下面这个链接。
https://www.jiuzhang.com/solution/merge-k-sorted-interval-lists#tag-other-lang-cpp
解法1:利用priority queue和tuple
tuple<i, j, interval>是存储intervals[][]中i行j列对应的interval。
第一步,先把每个vector的head pushd到priority_queue中,然后再将pq的top push_back到result vector中,同时对于的vector的j指针往右移位。这样,最终result vector就是一个按start排序的包含了所有interval的vector。
第二步,把result vector里面的interval 合并。
注意:
- operator() 的写法。其对应最小堆。
- tuple元素的get<0>(head), get<1>(head), get<2>(head)分别对应tuple的3个元素的引用。
- 合并完后记得将最后一个interval push_back到result中。
/**
* Definition of Interval:
* classs Interval {
* int start, end;
* Interval(int start, int end) {
* this->start = start;
* this->end = end;
* }
* }
*/
class cmp {
public:
bool operator() (tuple<int, int, Interval> &a, tuple<int, int, Interval> &b) {
return get<2>(a).start > get<2>(b).start;
}
};
class Solution {
public:
/**
* @param intervals: the given k sorted interval lists
* @return: the new sorted interval list
*/
vector<Interval> mergeKSortedIntervalLists(vector<vector<Interval>> &intervals) {
int len = intervals.size();
vector<Interval> result;
//tuple<int, int, Inteval> is for i,j,intervals[i][j]
priority_queue<tuple<int, int, Interval>, vector<tuple<int, int, Interval>>, cmp> pq;
//push the head interval of each vector (if not empty) into pq
for (int i = 0; i < len; ++i) {
if (intervals[i].size() != 0) {
pq.push(make_tuple(i, 0, intervals[i][0]));
}
}
while(!pq.empty()) {
tuple<int, int, Interval> head = pq.top();
pq.pop();
result.push_back(get<2>(head));
get<1>(head)++;
if (get<1>(head) < intervals[get<0>(head)].size()) {
get<2>(head) = intervals[get<0>(head)][get<1>(head)];
pq.push(head);
}
}
return merge(result);
}
private:
vector<Interval> merge(vector<Interval> &intervals) {
if (intervals.size() <= 1) return intervals;
vector<Interval> result;
int start = intervals[0].start;
int end = intervals[0].end;
for (auto interval: intervals) {
if (interval.start <= end) {
end = max(end, interval.end);
} else {
//no conflict, push_back current interval to result
result.push_back(Interval(start, end));
start = interval.start;
end = interval.end;
}
}
//push_back the last one
result.push_back(Interval(start, end));
return result;
}
};
解法2:
比较巧妙。先把所有interval的start和end都读入到map中。
map<int, int> key是start或end的值,value是该值的累加或累减值。若start不重复,则value=1,否则value++; 若end不重复,则value=-1,否则value–。
利用map的元素自动按key从小到大排列的特性,遍历所有元素,如果累加值count=0,说明一个新的interval开始了,把旧interval的start和end读入到result vector,同时开始设置start。
class Solution {
public:
/**
* @param intervals: the given k sorted interval lists
* @return: the new sorted interval list
*/
vector<Interval> mergeKSortedIntervalLists(vector<vector<Interval>> &intervals) {
int len = intervals.size();
vector<Interval> result;
map<int, int> mp;
for (int i = 0; i < len; ++i) {
for (int j = 0; j < intervals[i].size(); ++j) {
if (mp.find(intervals[i][j].start) == mp.end()) {
mp[intervals[i][j].start] = 1;
} else {
mp[intervals[i][j].start]++;
}
if (mp.find(intervals[i][j].end) == mp.end()) {
mp[intervals[i][j].end] = -1;
} else {
mp[intervals[i][j].end]--;
}
}
}
int count = 0;
int start = 0, end = 0;
bool newInterval = true;
for (auto i : mp) {
if (newInterval) {
start = i.first;
}
count += i.second;
if (count == 0) {
end = i.first;
result.push_back(Interval(start, end));
newInterval = true;
} else {
newInterval = false;
}
}
return result;
}
};