69
69
70
70
<!-- solution:start -->
71
71
72
- ### 方法一:二分查找
72
+ ### 方法一:排序 + 二分查找
73
+
74
+ 我们可以将区间的起点和下标存入数组 ` arr ` 中,并按照起点进行排序。然后遍历区间数组,对于每个区间 ` [_, ed] ` ,我们可以使用二分查找找到第一个起点大于等于 ` ed ` 的区间,即为其右侧区间,如果找到了,我们就将其下标存入答案数组中,否则存入 ` -1 ` 。
75
+
76
+ 时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为区间的长度。
73
77
74
78
<!-- tabs:start -->
75
79
@@ -78,15 +82,13 @@ tags:
78
82
``` python
79
83
class Solution :
80
84
def findRightInterval (self , intervals : List[List[int ]]) -> List[int ]:
81
- for i, v in enumerate (intervals):
82
- v.append(i)
83
- intervals.sort()
84
85
n = len (intervals)
85
86
ans = [- 1 ] * n
86
- for _, e, i in intervals:
87
- j = bisect_left(intervals, [e])
87
+ arr = sorted ((st, i) for i, (st, _) in enumerate (intervals))
88
+ for i, (_, ed) in enumerate (intervals):
89
+ j = bisect_left(arr, (ed, - inf))
88
90
if j < n:
89
- ans[i] = intervals [j][2 ]
91
+ ans[i] = arr [j][1 ]
90
92
return ans
91
93
```
92
94
@@ -96,27 +98,30 @@ class Solution:
96
98
class Solution {
97
99
public int [] findRightInterval (int [][] intervals ) {
98
100
int n = intervals. length;
99
- List<int[]> starts = new ArrayList<> ();
101
+ int [][] arr = new int [n][0 ];
102
+ for (int i = 0 ; i < n; ++ i) {
103
+ arr[i] = new int [] {intervals[i][0 ], i};
104
+ }
105
+ Arrays . sort(arr, (a, b) - > a[0 ] - b[0 ]);
106
+ int [] ans = new int [n];
100
107
for (int i = 0 ; i < n; ++ i) {
101
- starts. add(new int [] {intervals[i][0 ], i});
108
+ int j = search(arr, intervals[i][1 ]);
109
+ ans[i] = j < n ? arr[j][1 ] : - 1 ;
102
110
}
103
- starts. sort(Comparator . comparingInt(a - > a[0 ]));
104
- int [] res = new int [n];
105
- int i = 0 ;
106
- for (int [] interval : intervals) {
107
- int left = 0 , right = n - 1 ;
108
- int end = interval[1 ];
109
- while (left < right) {
110
- int mid = (left + right) >> 1 ;
111
- if (starts. get(mid)[0 ] >= end) {
112
- right = mid;
113
- } else {
114
- left = mid + 1 ;
115
- }
111
+ return ans;
112
+ }
113
+
114
+ private int search (int [][] arr , int x ) {
115
+ int l = 0 , r = arr. length;
116
+ while (l < r) {
117
+ int mid = (l + r) >> 1 ;
118
+ if (arr[mid][0 ] >= x) {
119
+ r = mid;
120
+ } else {
121
+ l = mid + 1 ;
116
122
}
117
- res[i++ ] = starts. get(left)[0 ] < end ? - 1 : starts. get(left)[1 ];
118
123
}
119
- return res ;
124
+ return l ;
120
125
}
121
126
}
122
127
```
@@ -128,61 +133,39 @@ class Solution {
128
133
public:
129
134
vector<int > findRightInterval(vector<vector<int >>& intervals) {
130
135
int n = intervals.size();
131
- vector<pair<int, int>> starts ;
136
+ vector<pair<int, int>> arr ;
132
137
for (int i = 0; i < n; ++i) {
133
- starts .emplace_back(make_pair( intervals[ i] [ 0 ] , i) );
138
+ arr .emplace_back(intervals[ i] [ 0 ] , i);
134
139
}
135
- sort(starts.begin(), starts.end());
136
- vector<int > res;
137
- for (auto interval : intervals) {
138
- int left = 0, right = n - 1;
139
- int end = interval[ 1] ;
140
- while (left < right) {
141
- int mid = left + right >> 1;
142
- if (starts[ mid] .first >= end)
143
- right = mid;
144
- else
145
- left = mid + 1;
146
- }
147
- res.push_back(starts[ left] .first < end ? -1 : starts[ left] .second);
140
+ sort(arr.begin(), arr.end());
141
+ vector<int > ans;
142
+ for (auto& e : intervals) {
143
+ int j = lower_bound(arr.begin(), arr.end(), make_pair(e[ 1] , -1)) - arr.begin();
144
+ ans.push_back(j == n ? -1 : arr[ j] .second);
148
145
}
149
- return res ;
146
+ return ans ;
150
147
}
151
148
};
152
149
```
153
150
154
151
#### Go
155
152
156
153
```go
157
- func findRightInterval(intervals [][]int) []int {
158
- n := len(intervals)
159
- starts := make([][]int, n)
160
- for i := 0; i < n; i++ {
161
- starts[i] = make([]int, 2)
162
- starts[i][0] = intervals[i][0]
163
- starts[i][1] = i
154
+ func findRightInterval(intervals [][]int) (ans []int) {
155
+ arr := make([][2]int, len(intervals))
156
+ for i, v := range intervals {
157
+ arr[i] = [2]int{v[0], i}
164
158
}
165
- sort.Slice(starts, func(i, j int) bool {
166
- return starts[i][0] < starts[j][0]
167
- })
168
- var res []int
169
- for _, interval := range intervals {
170
- left, right, end := 0, n-1, interval[1]
171
- for left < right {
172
- mid := (left + right) >> 1
173
- if starts[mid][0] >= end {
174
- right = mid
175
- } else {
176
- left = mid + 1
177
- }
178
- }
179
- val := -1
180
- if starts[left][0] >= end {
181
- val = starts[left][1]
159
+ sort.Slice(arr, func(i, j int) bool { return arr[i][0] < arr[j][0] })
160
+ for _, e := range intervals {
161
+ j := sort.Search(len(arr), func(i int) bool { return arr[i][0] >= e[1] })
162
+ if j < len(arr) {
163
+ ans = append(ans, arr[j][1])
164
+ } else {
165
+ ans = append(ans, -1)
182
166
}
183
- res = append(res, val)
184
167
}
185
- return res
168
+ return
186
169
}
187
170
```
188
171
@@ -191,28 +174,19 @@ func findRightInterval(intervals [][]int) []int {
191
174
``` ts
192
175
function findRightInterval(intervals : number [][]): number [] {
193
176
const n = intervals .length ;
194
- const starts = Array .from ({ length: n }).map (() => new Array <number >(2 ));
195
- for (let i = 0 ; i < n ; i ++ ) {
196
- starts [i ][0 ] = intervals [i ][0 ];
197
- starts [i ][1 ] = i ;
198
- }
199
- starts .sort ((a , b ) => a [0 ] - b [0 ]);
200
-
201
- return intervals .map (([_ , target ]) => {
202
- let left = 0 ;
203
- let right = n ;
204
- while (left < right ) {
205
- const mid = (left + right ) >>> 1 ;
206
- if (starts [mid ][0 ] < target ) {
207
- left = mid + 1 ;
177
+ const arr: number [][] = Array .from ({ length: n }, (_ , i ) => [intervals [i ][0 ], i ]);
178
+ arr .sort ((a , b ) => a [0 ] - b [0 ]);
179
+ return intervals .map (([_ , ed ]) => {
180
+ let [l, r] = [0 , n ];
181
+ while (l < r ) {
182
+ const mid = (l + r ) >> 1 ;
183
+ if (arr [mid ][0 ] >= ed ) {
184
+ r = mid ;
208
185
} else {
209
- right = mid ;
186
+ l = mid + 1 ;
210
187
}
211
188
}
212
- if (left >= n ) {
213
- return - 1 ;
214
- }
215
- return starts [left ][1 ];
189
+ return l < n ? arr [l ][1 ] : - 1 ;
216
190
});
217
191
}
218
192
```
0 commit comments