Skip to content

Commit d263df1

Browse files
authored
feat: add solutions to lc problem: No.2008 (#2068)
No.2008.Maximum Earnings From Taxi
1 parent 2ade258 commit d263df1

File tree

7 files changed

+393
-250
lines changed

7 files changed

+393
-250
lines changed

solution/2000-2099/2008.Maximum Earnings From Taxi/README.md

+140-84
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353

5454
**方法一:记忆化搜索 + 二分查找**
5555

56-
我们先将 `rides` 按照 `start` 从小到大排序,然后设计一个函数 $dfs(i)$,表示从第 $i$ 个乘客开始接单,最多能获得的小费。答案即为 $dfs(0)$。
56+
我们先将$rides$ 按照$start$ 从小到大排序,然后设计一个函数 $dfs(i)$,表示从第 $i$ 个乘客开始接单,最多能获得的小费。答案即为 $dfs(0)$。
5757

5858
函数 $dfs(i)$ 的计算过程如下:
5959

@@ -67,23 +67,23 @@ $$
6767

6868
此过程中,我们可以使用记忆化搜索,将每个状态的答案保存下来,避免重复计算。
6969

70-
时间复杂度 $O(m\times \log m)$,其中 $m$ 为 `rides` 的长度。
70+
时间复杂度 $O(m \times \log m)$,空间复杂度 $O(m)$。其中 $m$ 为$rides$ 的长度。
7171

7272
**方法二:动态规划 + 二分查找**
7373

7474
我们可以将方法一中的记忆化搜索改为动态规划。
7575

76-
先将 `rides` 排序,这次我们按照 `end` 从小到大排序。然后定义 $dp[i]$,表示前 $i$ 个乘客中,最多能获得的小费。答案即为 $dp[m]$。初始化 $dp[0] = 0$。
76+
先将 $rides$ 排序,这次我们按照 $end$ 从小到大排序。然后定义 $f[i]$,表示前 $i$ 个乘客中,最多能获得的小费。初始时 $f[0] = 0$,答案为 $f[m]$。
7777

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$。取两者的较大值即可。即:
7979

8080
$$
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)
8282
$$
8383

8484
其中 $j$ 是满足 $end_j \le start_i$ 的最大的下标,可以通过二分查找得到。
8585

86-
时间复杂度 $O(m\times \log m)$,其中 $m$ 为 `rides` 的长度。
86+
时间复杂度 $O(m \times \log m)$,空间复杂度 $O(m)$。其中 $m$ 为$rides$ 的长度。
8787

8888
相似题目:
8989

@@ -100,12 +100,12 @@ $$
100100
class Solution:
101101
def maxTaxiEarnings(self, n: int, rides: List[List[int]]) -> int:
102102
@cache
103-
def dfs(i):
103+
def dfs(i: int) -> int:
104104
if i >= len(rides):
105105
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)
109109

110110
rides.sort()
111111
return dfs(0)
@@ -115,12 +115,11 @@ class Solution:
115115
class Solution:
116116
def maxTaxiEarnings(self, n: int, rides: List[List[int]]) -> int:
117117
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]
124123
```
125124

126125
### **Java**
@@ -129,14 +128,14 @@ class Solution:
129128

130129
```java
131130
class Solution {
132-
private int[][] rides;
133-
private long[] f;
134131
private int m;
132+
private int[][] rides;
133+
private Long[] f;
135134

136135
public long maxTaxiEarnings(int n, int[][] rides) {
137-
m = rides.length;
138-
f = new long[m];
139136
Arrays.sort(rides, (a, b) -> a[0] - b[0]);
137+
m = rides.length;
138+
f = new Long[m];
140139
this.rides = rides;
141140
return dfs(0);
142141
}
@@ -145,27 +144,26 @@ class Solution {
145144
if (i >= m) {
146145
return 0;
147146
}
148-
if (f[i] != 0) {
147+
if (f[i] != null) {
149148
return f[i];
150149
}
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);
156154
}
157155

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;
162160
if (rides[mid][0] >= x) {
163-
right = mid;
161+
r = mid;
164162
} else {
165-
left = mid + 1;
163+
l = mid + 1;
166164
}
167165
}
168-
return left;
166+
return l;
169167
}
170168
}
171169
```
@@ -175,74 +173,73 @@ class Solution {
175173
public long maxTaxiEarnings(int n, int[][] rides) {
176174
Arrays.sort(rides, (a, b) -> a[1] - b[1]);
177175
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);
183182
}
184-
return dp[m];
183+
return f[m];
185184
}
186185

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;
193192
} else {
194-
left = mid + 1;
193+
l = mid + 1;
195194
}
196195
}
197-
return left;
196+
return l;
198197
}
199198
}
200199
```
201200

202201
### **C++**
203202

204203
```cpp
205-
using ll = long long;
206-
207204
class Solution {
208205
public:
209206
long long maxTaxiEarnings(int n, vector<vector<int>>& rides) {
210207
sort(rides.begin(), rides.end());
211208
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);
223222
};
224223
return dfs(0);
225224
}
226225
};
227226
```
228227
229228
```cpp
230-
using ll = long long;
231-
232229
class Solution {
233230
public:
234231
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]; });
236233
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);
244241
}
245-
return dp[m];
242+
return f.back();
246243
}
247244
};
248245
```
@@ -259,14 +256,12 @@ func maxTaxiEarnings(n int, rides [][]int) int64 {
259256
if i >= m {
260257
return 0
261258
}
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))
264263
}
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]
270265
}
271266
return dfs(0)
272267
}
@@ -276,13 +271,74 @@ func maxTaxiEarnings(n int, rides [][]int) int64 {
276271
func maxTaxiEarnings(n int, rides [][]int) int64 {
277272
sort.Slice(rides, func(i, j int) bool { return rides[i][1] < rides[j][1] })
278273
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))
284280
}
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];
286342
}
287343
```
288344

0 commit comments

Comments
 (0)