53
53
54
54
** 方法一:记忆化搜索 + 二分查找**
55
55
56
- 我们先将 ` rides ` 按照 ` start ` 从小到大排序,然后设计一个函数 $dfs(i)$,表示从第 $i$ 个乘客开始接单,最多能获得的小费。答案即为 $dfs(0)$。
56
+ 我们先将$ rides$ 按照$ start$ 从小到大排序,然后设计一个函数 $dfs(i)$,表示从第 $i$ 个乘客开始接单,最多能获得的小费。答案即为 $dfs(0)$。
57
57
58
58
函数 $dfs(i)$ 的计算过程如下:
59
59
67
67
68
68
此过程中,我们可以使用记忆化搜索,将每个状态的答案保存下来,避免重复计算。
69
69
70
- 时间复杂度 $O(m\times \log m)$,其中 $m$ 为 ` rides ` 的长度。
70
+ 时间复杂度 $O(m \times \log m)$,空间复杂度 $O(m)$。 其中 $m$ 为$ rides$ 的长度。
71
71
72
72
** 方法二:动态规划 + 二分查找**
73
73
74
74
我们可以将方法一中的记忆化搜索改为动态规划。
75
75
76
- 先将 ` rides ` 排序,这次我们按照 ` end ` 从小到大排序。然后定义 $dp [ i] $,表示前 $i$ 个乘客中,最多能获得的小费。答案即为 $dp [ m ] $。初始化 $dp [ 0] = 0$。
76
+ 先将 $ rides$ 排序,这次我们按照 $ end$ 从小到大排序。然后定义 $f [ i] $,表示前 $i$ 个乘客中,最多能获得的小费。初始时 $f [ 0] = 0$,答案为 $f [ m ] $。
77
77
78
- 对于第 $i$ 个乘客,我们可以选择接单,也可以选择不接单。如果不接单,那么最多能获得的小费为 $dp [ i ] $;如果接单,我们可以通过二分查找,找到在第 $i$ 个乘客上车地点之前,最后一个下车地点不大于 $start_i$ 的乘客,记为 $j$,那么最多能获得的小费为 $dp [ j] + end_i - start_i + tip_i$。取两者的较大值即可。即:
78
+ 对于第 $i$ 个乘客,我们可以选择接单,也可以选择不接单。如果不接单,那么最多能获得的小费为 $f [ i-1 ] $;如果接单,我们可以通过二分查找,找到在第 $i$ 个乘客上车地点之前,最后一个下车地点不大于 $start_i$ 的乘客,记为 $j$,那么最多能获得的小费为 $f [ j] + end_i - start_i + tip_i$。取两者的较大值即可。即:
79
79
80
80
$$
81
- dp [i] = \max(dp [i - 1], dp [j] + end_i - start_i + tip_i)
81
+ f [i] = \max(f [i - 1], f [j] + end_i - start_i + tip_i)
82
82
$$
83
83
84
84
其中 $j$ 是满足 $end_j \le start_i$ 的最大的下标,可以通过二分查找得到。
85
85
86
- 时间复杂度 $O(m\times \log m)$,其中 $m$ 为 ` rides ` 的长度。
86
+ 时间复杂度 $O(m \times \log m)$,空间复杂度 $O(m)$。 其中 $m$ 为$ rides$ 的长度。
87
87
88
88
相似题目:
89
89
100
100
class Solution :
101
101
def maxTaxiEarnings (self , n : int , rides : List[List[int ]]) -> int :
102
102
@cache
103
- def dfs (i ) :
103
+ def dfs (i : int ) -> int :
104
104
if i >= len (rides):
105
105
return 0
106
- s, e, t = rides[i]
107
- j = bisect_left(rides, e , lo = i + 1 , key = lambda x : x[0 ])
108
- return max (dfs(i + 1 ), dfs(j) + e - s + t )
106
+ st, ed, tip = rides[i]
107
+ j = bisect_left(rides, ed , lo = i + 1 , key = lambda x : x[0 ])
108
+ return max (dfs(i + 1 ), dfs(j) + ed - st + tip )
109
109
110
110
rides.sort()
111
111
return dfs(0 )
@@ -115,12 +115,11 @@ class Solution:
115
115
class Solution :
116
116
def maxTaxiEarnings (self , n : int , rides : List[List[int ]]) -> int :
117
117
rides.sort(key = lambda x : x[1 ])
118
- m = len (rides)
119
- dp = [0 ] * (m + 1 )
120
- for i, (s, e, t) in enumerate (rides):
121
- j = bisect_right(rides, s, hi = i, key = lambda x : x[1 ])
122
- dp[i + 1 ] = max (dp[i], dp[j] + e - s + t)
123
- return dp[m]
118
+ f = [0 ] * (len (rides) + 1 )
119
+ for i, (st, ed, tip) in enumerate (rides, 1 ):
120
+ j = bisect_left(rides, st + 1 , hi = i, key = lambda x : x[1 ])
121
+ f[i] = max (f[i - 1 ], f[j] + ed - st + tip)
122
+ return f[- 1 ]
124
123
```
125
124
126
125
### ** Java**
@@ -129,14 +128,14 @@ class Solution:
129
128
130
129
``` java
131
130
class Solution {
132
- private int [][] rides;
133
- private long [] f;
134
131
private int m;
132
+ private int [][] rides;
133
+ private Long [] f;
135
134
136
135
public long maxTaxiEarnings (int n , int [][] rides ) {
137
- m = rides. length;
138
- f = new long [m];
139
136
Arrays . sort(rides, (a, b) - > a[0 ] - b[0 ]);
137
+ m = rides. length;
138
+ f = new Long [m];
140
139
this . rides = rides;
141
140
return dfs(0 );
142
141
}
@@ -145,27 +144,26 @@ class Solution {
145
144
if (i >= m) {
146
145
return 0 ;
147
146
}
148
- if (f[i] != 0 ) {
147
+ if (f[i] != null ) {
149
148
return f[i];
150
149
}
151
- int s = rides[i][0 ], e = rides[i][1 ], t = rides[i][2 ];
152
- int j = search(rides, e, i + 1 );
153
- long ans = Math . max(dfs(i + 1 ), dfs(j) + e - s + t);
154
- f[i] = ans;
155
- return ans;
150
+ int [] r = rides[i];
151
+ int st = r[0 ], ed = r[1 ], tip = r[2 ];
152
+ int j = search(ed, i + 1 );
153
+ return f[i] = Math . max(dfs(i + 1 ), dfs(j) + ed - st + tip);
156
154
}
157
155
158
- private int search (int [][] rides , int x , int i ) {
159
- int left = i, right = m;
160
- while (left < right ) {
161
- int mid = (left + right ) >> 1 ;
156
+ private int search (int x , int l ) {
157
+ int r = m;
158
+ while (l < r ) {
159
+ int mid = (l + r ) >> 1 ;
162
160
if (rides[mid][0 ] >= x) {
163
- right = mid;
161
+ r = mid;
164
162
} else {
165
- left = mid + 1 ;
163
+ l = mid + 1 ;
166
164
}
167
165
}
168
- return left ;
166
+ return l ;
169
167
}
170
168
}
171
169
```
@@ -175,74 +173,73 @@ class Solution {
175
173
public long maxTaxiEarnings (int n , int [][] rides ) {
176
174
Arrays . sort(rides, (a, b) - > a[1 ] - b[1 ]);
177
175
int m = rides. length;
178
- long [] dp = new long [m + 1 ];
179
- for (int i = 0 ; i < m; ++ i) {
180
- int s = rides[i][0 ], e = rides[i][1 ], t = rides[i][2 ];
181
- int j = search(rides, s, i);
182
- dp[i + 1 ] = Math . max(dp[i], dp[j] + e - s + t);
176
+ long [] f = new long [m + 1 ];
177
+ for (int i = 1 ; i <= m; ++ i) {
178
+ int [] r = rides[i - 1 ];
179
+ int st = r[0 ], ed = r[1 ], tip = r[2 ];
180
+ int j = search(rides, st + 1 , i);
181
+ f[i] = Math . max(f[i - 1 ], f[j] + ed - st + tip);
183
182
}
184
- return dp [m];
183
+ return f [m];
185
184
}
186
185
187
- private int search (int [][] rides , int x , int n ) {
188
- int left = 0 , right = n ;
189
- while (left < right ) {
190
- int mid = (left + right ) >> 1 ;
191
- if (rides [mid][1 ] > x) {
192
- right = mid;
186
+ private int search (int [][] nums , int x , int r ) {
187
+ int l = 0 ;
188
+ while (l < r ) {
189
+ int mid = (l + r ) >> 1 ;
190
+ if (nums [mid][1 ] >= x) {
191
+ r = mid;
193
192
} else {
194
- left = mid + 1 ;
193
+ l = mid + 1 ;
195
194
}
196
195
}
197
- return left ;
196
+ return l ;
198
197
}
199
198
}
200
199
```
201
200
202
201
### ** C++**
203
202
204
203
``` cpp
205
- using ll = long long ;
206
-
207
204
class Solution {
208
205
public:
209
206
long long maxTaxiEarnings(int n, vector<vector<int >>& rides) {
210
207
sort(rides.begin(), rides.end());
211
208
int m = rides.size();
212
- vector<ll > f(m);
213
- vector<int > x(3);
214
- function<ll(int)> dfs = [ &] (int i) -> ll {
215
- if (i >= m) return 0;
216
- if (f[ i] ) return f[ i] ;
217
- int s = rides[ i] [ 0 ] , e = rides[ i] [ 1 ] , t = rides[ i] [ 2 ] ;
218
- x[ 0] = e;
219
- int j = lower_bound(rides.begin() + i + 1, rides.end(), x, [ &] (auto& l, auto& r) -> bool { return l[ 0] < r[ 0] ; }) - rides.begin();
220
- ll ans = max(dfs(i + 1), dfs(j) + e - s + t);
221
- f[ i] = ans;
222
- return ans;
209
+ long long f[ m] ;
210
+ memset(f, -1, sizeof(f));
211
+ function<long long(int)> dfs = [ &] (int i) -> long long {
212
+ if (i >= m) {
213
+ return 0;
214
+ }
215
+ if (f[ i] != -1) {
216
+ return f[ i] ;
217
+ }
218
+ auto& r = rides[ i] ;
219
+ int st = r[ 0] , ed = r[ 1] , tip = r[ 2] ;
220
+ int j = lower_bound(rides.begin() + i + 1, rides.end(), ed, [ ] (auto& a, int val) { return a[ 0] < val; }) - rides.begin();
221
+ return f[ i] = max(dfs(i + 1), dfs(j) + ed - st + tip);
223
222
};
224
223
return dfs(0);
225
224
}
226
225
};
227
226
```
228
227
229
228
```cpp
230
- using ll = long long;
231
-
232
229
class Solution {
233
230
public:
234
231
long long maxTaxiEarnings(int n, vector<vector<int>>& rides) {
235
- sort(rides.begin(), rides.end(), [&](auto& l, auto& r) -> bool { return l [1] < r [1]; });
232
+ sort(rides.begin(), rides.end(), [](const vector<int>& a, const vector<int>& b) { return a [1] < b [1]; });
236
233
int m = rides.size();
237
- vector<ll> dp (m + 1);
238
- vector<int> x(3);
239
- for (int i = 0; i < m; ++i) {
240
- int s = rides[i][ 0], e = rides[i][ 1], t = rides[i] [2];
241
- x[ 1] = s ;
242
- int j = upper_bound (rides.begin(), rides.begin() + i, x, [&](auto& l, auto& r) -> bool { return l[1] < r[1]; }) - rides.begin( );
243
- dp[i + 1 ] = max(dp[i ], dp [j] + e - s + t );
234
+ vector<long long> f (m + 1);
235
+ for (int i = 1; i <= m; ++i) {
236
+ auto& r = rides[i - 1];
237
+ int st = r[ 0], ed = r[ 1], tip = r [2];
238
+ auto it = lower_bound(rides.begin(), rides.begin() + i, st + 1, [](auto& a, int val) { return a[ 1] < val; }) ;
239
+ int j = distance (rides.begin(), it );
240
+ f[i ] = max(f[i - 1 ], f [j] + ed - st + tip );
244
241
}
245
- return dp[m] ;
242
+ return f.back() ;
246
243
}
247
244
};
248
245
```
@@ -259,14 +256,12 @@ func maxTaxiEarnings(n int, rides [][]int) int64 {
259
256
if i >= m {
260
257
return 0
261
258
}
262
- if f[i] != 0 {
263
- return f[i]
259
+ if f[i] == 0 {
260
+ st , ed , tip := rides[i][0 ], rides[i][1 ], rides[i][2 ]
261
+ j := sort.Search (m, func (j int ) bool { return rides[j][0 ] >= ed })
262
+ f[i] = max (dfs (i+1 ), int64 (ed-st+tip)+dfs (j))
264
263
}
265
- s , e , t := rides[i][0 ], rides[i][1 ], rides[i][2 ]
266
- j := sort.Search (m, func (k int ) bool { return rides[k][0 ] >= e })
267
- ans := max (dfs (i+1 ), dfs (j)+int64 (e-s+t))
268
- f[i] = ans
269
- return ans
264
+ return f[i]
270
265
}
271
266
return dfs (0 )
272
267
}
@@ -276,13 +271,74 @@ func maxTaxiEarnings(n int, rides [][]int) int64 {
276
271
func maxTaxiEarnings (n int , rides [][]int ) int64 {
277
272
sort.Slice (rides, func (i, j int ) bool { return rides[i][1 ] < rides[j][1 ] })
278
273
m := len (rides)
279
- dp := make ([]int64 , m+1 )
280
- for i , ride := range rides {
281
- s , e , t := ride[0 ], ride[1 ], ride[2 ]
282
- j := sort.Search (m, func (k int ) bool { return rides[k][1 ] > s })
283
- dp[i+1 ] = max (dp[i], dp[j]+int64 (e-s+t))
274
+ f := make ([]int64 , m+1 )
275
+ for i := 1 ; i <= m; i++ {
276
+ r := rides[i-1 ]
277
+ st , ed , tip := r[0 ], r[1 ], r[2 ]
278
+ j := sort.Search (m, func (j int ) bool { return rides[j][1 ] >= st+1 })
279
+ f[i] = max (f[i-1 ], f[j]+int64 (ed-st+tip))
284
280
}
285
- return dp[m]
281
+ return f[m]
282
+ }
283
+ ```
284
+
285
+ ### ** TypeScript**
286
+
287
+ ``` ts
288
+ function maxTaxiEarnings(n : number , rides : number [][]): number {
289
+ rides .sort ((a , b ) => a [0 ] - b [0 ]);
290
+ const m = rides .length ;
291
+ const f: number [] = Array (m ).fill (- 1 );
292
+ const search = (x : number , l : number ): number => {
293
+ let r = m ;
294
+ while (l < r ) {
295
+ const mid = (l + r ) >> 1 ;
296
+ if (rides [mid ][0 ] >= x ) {
297
+ r = mid ;
298
+ } else {
299
+ l = mid + 1 ;
300
+ }
301
+ }
302
+ return l ;
303
+ };
304
+ const dfs = (i : number ): number => {
305
+ if (i >= m ) {
306
+ return 0 ;
307
+ }
308
+ if (f [i ] === - 1 ) {
309
+ const [st, ed, tip] = rides [i ];
310
+ const j = search (ed , i + 1 );
311
+ f [i ] = Math .max (dfs (i + 1 ), dfs (j ) + ed - st + tip );
312
+ }
313
+ return f [i ];
314
+ };
315
+ return dfs (0 );
316
+ }
317
+ ```
318
+
319
+ ``` ts
320
+ function maxTaxiEarnings(n : number , rides : number [][]): number {
321
+ rides .sort ((a , b ) => a [1 ] - b [1 ]);
322
+ const m = rides .length ;
323
+ const f: number [] = Array (m + 1 ).fill (0 );
324
+ const search = (x : number , r : number ): number => {
325
+ let l = 0 ;
326
+ while (l < r ) {
327
+ const mid = (l + r ) >> 1 ;
328
+ if (rides [mid ][1 ] >= x ) {
329
+ r = mid ;
330
+ } else {
331
+ l = mid + 1 ;
332
+ }
333
+ }
334
+ return l ;
335
+ };
336
+ for (let i = 1 ; i <= m ; ++ i ) {
337
+ const [st, ed, tip] = rides [i - 1 ];
338
+ const j = search (st + 1 , i );
339
+ f [i ] = Math .max (f [i - 1 ], f [j ] + ed - st + tip );
340
+ }
341
+ return f [m ];
286
342
}
287
343
```
288
344
0 commit comments