Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LeetCode] 436. Find Right Interval #436

Open
grandyang opened this issue May 30, 2019 · 1 comment
Open

[LeetCode] 436. Find Right Interval #436

grandyang opened this issue May 30, 2019 · 1 comment

Comments

@grandyang
Copy link
Owner

grandyang commented May 30, 2019

 

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:

  1. You may assume the interval's end point is always bigger than its start point.
  2. 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.

 

这道题给了我们一堆区间,让我们找每个区间的最近右区间,要保证右区间的 start 要大于等于当前区间的 end,由于区间的顺序不能变,所以我们不能给区间排序,我们需要建立区间的 start 和该区间位置之间的映射,由于题目中限定了每个区间的 start 都不同,所以不用担心一对多的情况出现。然后我们把所有的区间的 start 都放到一个数组中,并对这个数组进行降序排序,那么 start 值大的就在数组前面。然后我们遍历区间集合,对于每个区间,我们在数组中找第一个小于当前区间的 end 值的位置,如果数组中第一个数就小于当前区间的 end,那么说明该区间不存在右区间,结果 res 中加入-1;如果找到了第一个小于当前区间 end 的位置,那么往前推一个就是第一个大于等于当前区间 end 的 start,我们在 HashMap 中找到该区间的坐标加入结果 res 中即可,参见代码如下:

 

解法一:

class Solution {
public:
    vector<int> findRightInterval(vector<vector<int>>& intervals) {
        vector<int> res, starts;
        unordered_map<int, int> m;
        for (int i = 0; i < intervals.size(); ++i) {
            m[intervals[i][0]] = i;
            starts.push_back(intervals[i][0]);
        }
        sort(starts.rbegin(), starts.rend());
        for (auto interval : intervals) {
            int i = 0;
            for (; i < starts.size(); ++i) {
                if (starts[i] < interval[1]) break;
            }
            res.push_back((i > 0) ? m[starts[i - 1]] : -1);
        }
        return res;
    }
};

 

上面的解法可以进一步化简,我们可以利用 STL 的 lower_bound 函数来找第一个不小于目标值的位置,这样也可以达到我们的目标,参见代码如下:

 

解法二:

class Solution {
public:
    vector<int> findRightInterval(vector<vector<int>>& intervals) {
        vector<int> res;
        map<int, int> m;
        for (int i = 0; i < intervals.size(); ++i) {
            m[intervals[i][0]] = i;
        }
        for (auto interval : intervals) {
            auto it = m.lower_bound(interval[1]);
            if (it == m.end()) res.push_back(-1);
            else res.push_back(it->second);
        }
        return res;
    }
};

 

Github 同步地址:

#436

 

类似题目:

Non-overlapping Intervals

Data Stream as Disjoint Intervals 

Insert Interval

Merge Intervals

 

参考资料:

https://leetcode.com/problems/find-right-interval/

https://leetcode.com/problems/find-right-interval/discuss/91819/C%2B%2B-map-solution

https://leetcode.com/problems/find-right-interval/discuss/91789/Java-clear-O(n-logn)-solution-based-on-TreeMap

 

LeetCode All in One 题目讲解汇总(持续更新中...)

@Sahilamin219
Copy link

Sahilamin219 commented Feb 11, 2021

Another approach without any STL is :
store hashed intervals with there indexes.
You can store both starting and ending intervals and short them .
After that just do a liner scan for each ending intervals .
Time:N*log(N)
Space:O(N)
Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants