Skip to content

Commit b488904

Browse files
authored
feat: add solutions to lc problem: No.2187 (#2792)
1 parent fbbb30b commit b488904

File tree

5 files changed

+102
-47
lines changed

5 files changed

+102
-47
lines changed

solution/2100-2199/2187.Minimum Time to Complete Trips/README.md

+38-16
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,15 @@
5050

5151
## 解法
5252

53-
### 方法一
53+
### 方法一:二分查找
54+
55+
我们注意到,如果我们能在 $t$ 时间内至少完成 $totalTrips$ 趟旅途,那么在 $t' > t$ 时间内也能至少完成 $totalTrips$ 趟旅途。因此我们可以使用二分查找的方法来找到最小的 $t$。
56+
57+
我们定义二分查找的左边界 $l = 1$,右边界 $r = \min(time) \times \text{totalTrips}$。每一次二分查找,我们计算中间值 $\text{mid} = \frac{l + r}{2}$,然后计算在 $\text{mid}$ 时间内能完成的旅途数目。如果这个数目大于等于 $\text{totalTrips}$,那么我们将右边界缩小到 $\text{mid}$,否则我们将左边界扩大到 $\text{mid} + 1$。
58+
59+
最后返回左边界即可。
60+
61+
时间复杂度 $O(n \times \log(m \times k))$,其中 $n$ 和 $k$ 分别是数组 $time$ 的长度和 $totalTrips$,而 $m$ 是数组 $time$ 中的最小值。空间复杂度 $O(1)$。
5462

5563
<!-- tabs:start -->
5664

@@ -93,15 +101,18 @@ class Solution {
93101
public:
94102
long long minimumTime(vector<int>& time, int totalTrips) {
95103
int mi = *min_element(time.begin(), time.end());
96-
long long left = 1, right = (long long) mi * totalTrips;
104+
long long left = 1, right = 1LL * mi * totalTrips;
97105
while (left < right) {
98106
long long cnt = 0;
99107
long long mid = (left + right) >> 1;
100-
for (int v : time) cnt += mid / v;
101-
if (cnt >= totalTrips)
108+
for (int v : time) {
109+
cnt += mid / v;
110+
}
111+
if (cnt >= totalTrips) {
102112
right = mid;
103-
else
113+
} else {
104114
left = mid + 1;
115+
}
105116
}
106117
return left;
107118
}
@@ -110,20 +121,31 @@ public:
110121
111122
```go
112123
func minimumTime(time []int, totalTrips int) int64 {
113-
left, right := 1, slices.Min(time)*totalTrips
114-
for left < right {
115-
mid := (left + right) >> 1
124+
mx := slices.Min(time) * totalTrips
125+
return int64(sort.Search(mx, func(x int) bool {
116126
cnt := 0
117127
for _, v := range time {
118-
cnt += mid / v
128+
cnt += x / v
119129
}
120-
if cnt >= totalTrips {
121-
right = mid
122-
} else {
123-
left = mid + 1
124-
}
125-
}
126-
return int64(left)
130+
return cnt >= totalTrips
131+
}))
132+
}
133+
```
134+
135+
```ts
136+
function minimumTime(time: number[], totalTrips: number): number {
137+
let left = 1n;
138+
let right = BigInt(Math.min(...time)) * BigInt(totalTrips);
139+
while (left < right) {
140+
const mid = (left + right) >> 1n;
141+
const cnt = time.reduce((acc, v) => acc + mid / BigInt(v), 0n);
142+
if (cnt >= BigInt(totalTrips)) {
143+
right = mid;
144+
} else {
145+
left = mid + 1n;
146+
}
147+
}
148+
return Number(left);
127149
}
128150
```
129151

solution/2100-2199/2187.Minimum Time to Complete Trips/README_EN.md

+38-16
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,15 @@ So the minimum time needed to complete 1 trip is 2.
4848

4949
## Solutions
5050

51-
### Solution 1
51+
### Solution 1: Binary Search
52+
53+
We notice that if we can complete at least $totalTrips$ trips in $t$ time, then we can also complete at least $totalTrips$ trips in $t' > t$ time. Therefore, we can use the method of binary search to find the smallest $t$.
54+
55+
We define the left boundary of the binary search as $l = 1$, and the right boundary as $r = \min(time) \times totalTrips$. For each binary search, we calculate the middle value $\text{mid} = \frac{l + r}{2}$, and then calculate the number of trips that can be completed in $\text{mid}$ time. If this number is greater than or equal to $totalTrips$, then we reduce the right boundary to $\text{mid}$, otherwise we increase the left boundary to $\text{mid} + 1$.
56+
57+
Finally, return the left boundary.
58+
59+
The time complexity is $O(n \times \log(m \times k))$, where $n$ and $k$ are the length of the array $time$ and $totalTrips$ respectively, and $m$ is the minimum value in the array $time$. The space complexity is $O(1)$.
5260

5361
<!-- tabs:start -->
5462

@@ -91,15 +99,18 @@ class Solution {
9199
public:
92100
long long minimumTime(vector<int>& time, int totalTrips) {
93101
int mi = *min_element(time.begin(), time.end());
94-
long long left = 1, right = (long long) mi * totalTrips;
102+
long long left = 1, right = 1LL * mi * totalTrips;
95103
while (left < right) {
96104
long long cnt = 0;
97105
long long mid = (left + right) >> 1;
98-
for (int v : time) cnt += mid / v;
99-
if (cnt >= totalTrips)
106+
for (int v : time) {
107+
cnt += mid / v;
108+
}
109+
if (cnt >= totalTrips) {
100110
right = mid;
101-
else
111+
} else {
102112
left = mid + 1;
113+
}
103114
}
104115
return left;
105116
}
@@ -108,20 +119,31 @@ public:
108119
109120
```go
110121
func minimumTime(time []int, totalTrips int) int64 {
111-
left, right := 1, slices.Min(time)*totalTrips
112-
for left < right {
113-
mid := (left + right) >> 1
122+
mx := slices.Min(time) * totalTrips
123+
return int64(sort.Search(mx, func(x int) bool {
114124
cnt := 0
115125
for _, v := range time {
116-
cnt += mid / v
126+
cnt += x / v
117127
}
118-
if cnt >= totalTrips {
119-
right = mid
120-
} else {
121-
left = mid + 1
122-
}
123-
}
124-
return int64(left)
128+
return cnt >= totalTrips
129+
}))
130+
}
131+
```
132+
133+
```ts
134+
function minimumTime(time: number[], totalTrips: number): number {
135+
let left = 1n;
136+
let right = BigInt(Math.min(...time)) * BigInt(totalTrips);
137+
while (left < right) {
138+
const mid = (left + right) >> 1n;
139+
const cnt = time.reduce((acc, v) => acc + mid / BigInt(v), 0n);
140+
if (cnt >= BigInt(totalTrips)) {
141+
right = mid;
142+
} else {
143+
left = mid + 1n;
144+
}
145+
}
146+
return Number(left);
125147
}
126148
```
127149

solution/2100-2199/2187.Minimum Time to Complete Trips/Solution.cpp

+7-4
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,18 @@ class Solution {
22
public:
33
long long minimumTime(vector<int>& time, int totalTrips) {
44
int mi = *min_element(time.begin(), time.end());
5-
long long left = 1, right = (long long) mi * totalTrips;
5+
long long left = 1, right = 1LL * mi * totalTrips;
66
while (left < right) {
77
long long cnt = 0;
88
long long mid = (left + right) >> 1;
9-
for (int v : time) cnt += mid / v;
10-
if (cnt >= totalTrips)
9+
for (int v : time) {
10+
cnt += mid / v;
11+
}
12+
if (cnt >= totalTrips) {
1113
right = mid;
12-
else
14+
} else {
1315
left = mid + 1;
16+
}
1417
}
1518
return left;
1619
}
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,10 @@
11
func minimumTime(time []int, totalTrips int) int64 {
2-
left, right := 1, slices.Min(time)*totalTrips
3-
for left < right {
4-
mid := (left + right) >> 1
2+
mx := slices.Min(time) * totalTrips
3+
return int64(sort.Search(mx, func(x int) bool {
54
cnt := 0
65
for _, v := range time {
7-
cnt += mid / v
6+
cnt += x / v
87
}
9-
if cnt >= totalTrips {
10-
right = mid
11-
} else {
12-
left = mid + 1
13-
}
14-
}
15-
return int64(left)
8+
return cnt >= totalTrips
9+
}))
1610
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
function minimumTime(time: number[], totalTrips: number): number {
2+
let left = 1n;
3+
let right = BigInt(Math.min(...time)) * BigInt(totalTrips);
4+
while (left < right) {
5+
const mid = (left + right) >> 1n;
6+
const cnt = time.reduce((acc, v) => acc + mid / BigInt(v), 0n);
7+
if (cnt >= BigInt(totalTrips)) {
8+
right = mid;
9+
} else {
10+
left = mid + 1n;
11+
}
12+
}
13+
return Number(left);
14+
}

0 commit comments

Comments
 (0)