comments | difficulty | edit_url | tags | |||
---|---|---|---|---|---|---|
true |
Medium |
|
You are given an array of intervals
, where intervals[i] = [starti, endi]
and each starti
is unique.
The right interval for an interval i
is an interval j
such that startj >= endi
and startj
is minimized. Note that i
may equal j
.
Return an array of right interval indices for each interval i
. If no right interval exists for interval i
, then put -1
at index i
.
Example 1:
Input: intervals = [[1,2]] Output: [-1] Explanation: There is only one interval in the collection, so it outputs -1.
Example 2:
Input: intervals = [[3,4],[2,3],[1,2]] Output: [-1,0,1] Explanation: There is no right interval for [3,4]. The right interval for [2,3] is [3,4] since start0 = 3 is the smallest start that is >= end1 = 3. The right interval for [1,2] is [2,3] since start1 = 2 is the smallest start that is >= end2 = 2.
Example 3:
Input: intervals = [[1,4],[2,3],[3,4]] Output: [-1,2,-1] Explanation: There is no right interval for [1,4] and [3,4]. The right interval for [2,3] is [3,4] since start2 = 3 is the smallest start that is >= end1 = 3.
Constraints:
1 <= intervals.length <= 2 * 104
intervals[i].length == 2
-106 <= starti <= endi <= 106
- The start point of each interval is unique.
We can store the start point and index of each interval into an array arr
, and sort it by the start point. Then we iterate through the interval array, for each interval [_, ed]
, we can use binary search to find the first interval whose start point is greater than or equal to ed
, which is its right-side interval. If found, we store its index into the answer array, otherwise, we store -1
.
The time complexity is
class Solution:
def findRightInterval(self, intervals: List[List[int]]) -> List[int]:
n = len(intervals)
ans = [-1] * n
arr = sorted((st, i) for i, (st, _) in enumerate(intervals))
for i, (_, ed) in enumerate(intervals):
j = bisect_left(arr, (ed, -inf))
if j < n:
ans[i] = arr[j][1]
return ans
class Solution {
public int[] findRightInterval(int[][] intervals) {
int n = intervals.length;
int[][] arr = new int[n][0];
for (int i = 0; i < n; ++i) {
arr[i] = new int[] {intervals[i][0], i};
}
Arrays.sort(arr, (a, b) -> a[0] - b[0]);
int[] ans = new int[n];
for (int i = 0; i < n; ++i) {
int j = search(arr, intervals[i][1]);
ans[i] = j < n ? arr[j][1] : -1;
}
return ans;
}
private int search(int[][] arr, int x) {
int l = 0, r = arr.length;
while (l < r) {
int mid = (l + r) >> 1;
if (arr[mid][0] >= x) {
r = mid;
} else {
l = mid + 1;
}
}
return l;
}
}
class Solution {
public:
vector<int> findRightInterval(vector<vector<int>>& intervals) {
int n = intervals.size();
vector<pair<int, int>> arr;
for (int i = 0; i < n; ++i) {
arr.emplace_back(intervals[i][0], i);
}
sort(arr.begin(), arr.end());
vector<int> ans;
for (auto& e : intervals) {
int j = lower_bound(arr.begin(), arr.end(), make_pair(e[1], -1)) - arr.begin();
ans.push_back(j == n ? -1 : arr[j].second);
}
return ans;
}
};
func findRightInterval(intervals [][]int) (ans []int) {
arr := make([][2]int, len(intervals))
for i, v := range intervals {
arr[i] = [2]int{v[0], i}
}
sort.Slice(arr, func(i, j int) bool { return arr[i][0] < arr[j][0] })
for _, e := range intervals {
j := sort.Search(len(arr), func(i int) bool { return arr[i][0] >= e[1] })
if j < len(arr) {
ans = append(ans, arr[j][1])
} else {
ans = append(ans, -1)
}
}
return
}
function findRightInterval(intervals: number[][]): number[] {
const n = intervals.length;
const arr: number[][] = Array.from({ length: n }, (_, i) => [intervals[i][0], i]);
arr.sort((a, b) => a[0] - b[0]);
return intervals.map(([_, ed]) => {
let [l, r] = [0, n];
while (l < r) {
const mid = (l + r) >> 1;
if (arr[mid][0] >= ed) {
r = mid;
} else {
l = mid + 1;
}
}
return l < n ? arr[l][1] : -1;
});
}