题目描述
给你一个区间数组 intervals
,其中 intervals[i] = [starti, endi]
,且每个 starti
都 不同 。
区间 i
的 右侧区间 可以记作区间 j
,并满足 startj
>= endi
,且 startj
最小化 。注意 i
可能等于 j
。
返回一个由每个区间 i
的 右侧区间 在 intervals
中对应下标组成的数组。如果某个区间 i
不存在对应的 右侧区间 ,则下标 i
处的值设为 -1
。
示例 1:
输入:intervals = [[1,2]]
输出:[-1]
解释:集合中只有一个区间,所以输出-1。
示例 2:
输入:intervals = [[3,4],[2,3],[1,2]]
输出:[-1,0,1]
解释:对于 [3,4] ,没有满足条件的“右侧”区间。
对于 [2,3] ,区间[3,4]具有最小的“右”起点;
对于 [1,2] ,区间[2,3]具有最小的“右”起点。
示例 3:
输入:intervals = [[1,4],[2,3],[3,4]]
输出:[-1,2,-1]
解释:对于区间 [1,4] 和 [3,4] ,没有满足条件的“右侧”区间。
对于 [2,3] ,区间 [3,4] 有最小的“右”起点。
提示:
1 <= intervals.length <= 2 * 104
intervals[i].length == 2
-106 <= starti <= endi <= 106
- 每个间隔的起点都 不相同
解法
方法一:排序 + 二分查找
我们可以将区间的起点和下标存入数组 arr
中,并按照起点进行排序。然后遍历区间数组,对于每个区间 [_, ed]
,我们可以使用二分查找找到第一个起点大于等于 ed
的区间,即为其右侧区间,如果找到了,我们就将其下标存入答案数组中,否则存入 -1
。
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为区间的长度。
| 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
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 | 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;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | 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;
}
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | 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
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | 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;
});
}
|