题目:
Given a set of intervals, for each of the interval i, check if there exists an interval j whose start point is bigger than or equal to the end point of the interval i, which can be called that j is on the "right" of i.
For any interval i, you need to store the minimum interval j's index, which means that the interval j has the minimum start point to build the "right" relationship for interval i. If the interval j doesn't exist, store -1 for the interval i. Finally, you need output the stored value of each interval as an array.
Note:
- You may assume the interval's end point is always bigger than its start point.
- You may assume none of these intervals have the same start point.
Example 1:
Input: [ [1,2] ] Output: [-1] Explanation: There is only one interval in the collection, so it outputs -1.
Example 2:
Input: [ [3,4], [2,3], [1,2] ] Output: [-1, 0, 1] Explanation: There is no satisfied "right" interval for [3,4]. For [2,3], the interval [3,4] has minimum-"right" start point; For [1,2], the interval [2,3] has minimum-"right" start point.
Example 3:
Input: [ [1,4], [2,3], [3,4] ] Output: [-1, 2, -1] Explanation: There is no satisfied "right" interval for [1,4] and [3,4]. For [2,3], the interval [3,4] has minimum-"right" start point.
思路:
我的基本思路是:首先对intervals的各个起点和终点进行排序,然后维护一个end点所对应的索引的集合,并且从左到右遍历:如果遇到一个end点,则将该点加入集合中;否则说明遇到了start点,我们就将当前集合中的所有indices所对应的right interval的索引都置为当前start点在原来序列中所对应的index(有点绕,请仔细理解)。
思路不难,关键在于数据结构的设计和实现,请见下面的代码片段。当然算法的时间复杂度为O(nlogn),这是由于排序所致。空间复杂度仍然为O(1)。
代码:
/**
* Definition for an interval.
* struct Interval {
* int start;
* int end;
* Interval() : start(0), end(0) {}
* Interval(int s, int e) : start(s), end(e) {}
* };
*/
class Solution {
public:
vector<int> findRightInterval(vector<Interval>& intervals) {
vector<ReverseIndex> ri;
for (int i = 0; i < intervals.size(); ++i) {
ri.push_back(ReverseIndex(intervals[i].start, i, true));
ri.push_back(ReverseIndex(intervals[i].end, i, false));
}
sort(ri.begin(), ri.end(), RIComp);
vector<int> ret(intervals.size(), -1);
vector<int> indices; // store the end indices
for (int i = 0; i < ri.size(); ++i) {
if (ri[i].start == true) {
for (auto index : indices) {
ret[index] = ri[i].index;
}
indices.clear();
}
else {
indices.push_back(ri[i].index);
}
}
return ret;
}
private:
struct ReverseIndex {
int value;
int index;
bool start;
ReverseIndex(int v, int i, bool s) {
value = v, index = i, start = s;
}
};
struct ReverseIndexCompare {
bool operator() (const ReverseIndex &a, const ReverseIndex &b) const {
if (a.value < b.value) {
return true;
}
else if (a.value > b.value) {
return false;
}
else { // end point should come first
return a.start < b.start;
}
}
} RIComp;
};