0%

『LeetCode』436 寻找右区间

题目

436. 寻找右区间

给你一个区间数组 \(intervals\) ,其中 \(intervals[i] = [start_{i}, end_{i}]\) ,且每个 \(start_{i}\)不同

区间 \(i\)右侧区间 可以记作区间 \(j\) ,并满足 \(start_{j} >= end_{i}\) ,且 \(start_{j}\) 最小化

返回一个由每个区间 \(i\)右侧区间 的最小起始位置组成的数组。如果某个区间 \(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 * 10^4\)
  • \(intervals[i].length == 2\)
  • \(-10^6 <= start_i <= end_i <= 10^6\)
  • 每个间隔的起点都 不相同

相似题目


题解

【寻找右区间】排序二分

按左端点排序,然后遍历逐个二分查找符合要求的右侧区间即可。

注意:题目要求对返回原始下标,可以建立一个“下标”数组进行排序而不改变原数组。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Code language: Python
class Solution:
def findRightInterval(self, intervals: List[List[int]]) -> List[int]:
n = len(intervals)
s = sorted(range(n), key=lambda x: intervals[x][0])
ans = list()
l, r = intervals[s[0]][0], intervals[s[-1]][0]
for x, y in intervals:
if y < l or y > r:
ans.append(-1)
else:
left, right = 0, n - 1
while left < right:
mid = (left + right) >> 1
if y > intervals[s[mid]][0]:
left = mid + 1
else:
right = mid
ans.append(s[left])
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
// Code language: Java
class Solution {
public int[] findRightInterval(int[][] intervals) {
int n =intervals.length;
int[] ans = new int[n];
int[][] s = new int[n][2];
for (int i = 0; i < n; ++i) {
s[i][0] = intervals[i][0];
s[i][1] = i;
}
Arrays.sort(s, (a,b)->a[0]-b[0]);
for (int i = 0; i < n; ++i) {
int y = intervals[i][1];
if (y < s[0][0] || y > s[n - 1][0]) ans[i] = -1;
else {
int left = 0, right = n - 1;
while (left < right) {
int mid = (left + right) >> 1;
if (y > s[mid][0])
left = mid + 1;
else
right = mid;
}
ans[i] = s[left][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
30
// Code language: Cpp
class Solution {
public:
vector<int> findRightInterval(vector<vector<int>>& intervals) {
int n =intervals.size();
vector<int> ans(n);
vector<pair<int, int>> s(n, pair<int, int>());
for (int i = 0; i < n; ++i) {
s[i].first = intervals[i][0];
s[i].second = i;
}
sort(s.begin(), s.end());
for (int i = 0; i < n; ++i) {
int y = intervals[i][1];
if (y < s[0].first || y > s[n - 1].first) ans[i] = -1;
else {
int left = 0, right = n - 1;
while (left < right) {
int mid = (left + right) >> 1;
if (y > s[mid].first)
left = mid + 1;
else
right = mid;
}
ans[i] = s[left].second;
}
}
return ans;
}
};
  • 时间复杂度: \(O(n \log n)\)
  • 空间复杂度: \(O(n)\)
--- ♥ end ♥ ---

欢迎关注我呀~