Skip to content

Commit a7a4a1b

Browse files
authored
feat: update solutions to lc problem: No.436 (#3030)
1 parent bd50c80 commit a7a4a1b

File tree

7 files changed

+172
-254
lines changed

7 files changed

+172
-254
lines changed

solution/0400-0499/0436.Find Right Interval/README.md

+59-85
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,11 @@ tags:
6969

7070
<!-- solution:start -->
7171

72-
### 方法一:二分查找
72+
### 方法一:排序 + 二分查找
73+
74+
我们可以将区间的起点和下标存入数组 `arr` 中,并按照起点进行排序。然后遍历区间数组,对于每个区间 `[_, ed]`,我们可以使用二分查找找到第一个起点大于等于 `ed` 的区间,即为其右侧区间,如果找到了,我们就将其下标存入答案数组中,否则存入 `-1`
75+
76+
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为区间的长度。
7377

7478
<!-- tabs:start -->
7579

@@ -78,15 +82,13 @@ tags:
7882
```python
7983
class Solution:
8084
def findRightInterval(self, intervals: List[List[int]]) -> List[int]:
81-
for i, v in enumerate(intervals):
82-
v.append(i)
83-
intervals.sort()
8485
n = len(intervals)
8586
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))
8890
if j < n:
89-
ans[i] = intervals[j][2]
91+
ans[i] = arr[j][1]
9092
return ans
9193
```
9294

@@ -96,27 +98,30 @@ class Solution:
9698
class Solution {
9799
public int[] findRightInterval(int[][] intervals) {
98100
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];
100107
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;
102110
}
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;
116122
}
117-
res[i++] = starts.get(left)[0] < end ? -1 : starts.get(left)[1];
118123
}
119-
return res;
124+
return l;
120125
}
121126
}
122127
```
@@ -128,61 +133,39 @@ class Solution {
128133
public:
129134
vector<int> findRightInterval(vector<vector<int>>& intervals) {
130135
int n = intervals.size();
131-
vector<pair<int, int>> starts;
136+
vector<pair<int, int>> arr;
132137
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);
134139
}
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);
148145
}
149-
return res;
146+
return ans;
150147
}
151148
};
152149
```
153150
154151
#### Go
155152
156153
```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}
164158
}
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)
182166
}
183-
res = append(res, val)
184167
}
185-
return res
168+
return
186169
}
187170
```
188171

@@ -191,28 +174,19 @@ func findRightInterval(intervals [][]int) []int {
191174
```ts
192175
function findRightInterval(intervals: number[][]): number[] {
193176
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;
208185
} else {
209-
right = mid;
186+
l = mid + 1;
210187
}
211188
}
212-
if (left >= n) {
213-
return -1;
214-
}
215-
return starts[left][1];
189+
return l < n ? arr[l][1] : -1;
216190
});
217191
}
218192
```

0 commit comments

Comments
 (0)