题目
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 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 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 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)\)