Skip to content

Commit c7bbaf8

Browse files
authored
Update README_EN.md
1 parent 5bb27b2 commit c7bbaf8

File tree

1 file changed

+143
-119
lines changed
  • solution/1800-1899/1870.Minimum Speed to Arrive on Time

1 file changed

+143
-119
lines changed

solution/1800-1899/1870.Minimum Speed to Arrive on Time/README_EN.md

Lines changed: 143 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,17 @@ tags:
8181

8282
<!-- solution:start -->
8383

84-
### Solution 1
84+
### Solution 1: Binary Search
85+
86+
We notice that if a speed value $v$ allows us to arrive within the stipulated time, then for any $v' > v$, we can also definitely arrive within the stipulated time. This exhibits monotonicity, hence we can use binary search to find the smallest speed value that meets the condition.
87+
88+
We can enumerate the speed value using binary search. First, we define the left and right boundaries of the binary search as $l = 1$, $r = 10^7 + 1$, and then we take the middle value $\text{mid} = \frac{l + r}{2}$ each time to check if it meets the condition. If it does, we move the right boundary to $\text{mid}$; otherwise, we move the left boundary to $\text{mid} + 1$.
89+
90+
The problem is transformed into determining whether a speed value $v$ can allow us to arrive within the stipulated time. We can traverse each train trip, calculate the running time of each trip $t = \frac{d}{v}$, if it is the last trip, we directly add $t$; otherwise, we round up and add $t$. Finally, we check if the total time is less than or equal to the stipulated time, if so, it means the condition is met.
91+
92+
After the binary search ends, if the left boundary exceeds $10^7$, it means we cannot arrive within the stipulated time, and we return $-1$; otherwise, we return the left boundary.
93+
94+
The time complexity is $O(n \times \log M)$, where $n$ and $M$ are the number of train trips and the upper bound of the speed, respectively. The space complexity is $O(1)$.
8595

8696
<!-- tabs:start -->
8797

@@ -90,12 +100,15 @@ tags:
90100
```python
91101
class Solution:
92102
def minSpeedOnTime(self, dist: List[int], hour: float) -> int:
93-
def check(speed):
94-
res = 0
103+
def check(v: int) -> bool:
104+
s = 0
95105
for i, d in enumerate(dist):
96-
res += (d / speed) if i == len(dist) - 1 else math.ceil(d / speed)
97-
return res <= hour
106+
t = d / v
107+
s += t if i == len(dist) - 1 else ceil(t)
108+
return s <= hour
98109

110+
if len(dist) > ceil(hour):
111+
return -1
99112
r = 10**7 + 1
100113
ans = bisect_left(range(1, r), True, key=check) + 1
101114
return -1 if ans == r else ans
@@ -106,25 +119,30 @@ class Solution:
106119
```java
107120
class Solution {
108121
public int minSpeedOnTime(int[] dist, double hour) {
109-
int left = 1, right = (int) 1e7;
110-
while (left < right) {
111-
int mid = (left + right) >> 1;
122+
if (dist.length > Math.ceil(hour)) {
123+
return -1;
124+
}
125+
final int m = (int) 1e7;
126+
int l = 1, r = m + 1;
127+
while (l < r) {
128+
int mid = (l + r) >> 1;
112129
if (check(dist, mid, hour)) {
113-
right = mid;
130+
r = mid;
114131
} else {
115-
left = mid + 1;
132+
l = mid + 1;
116133
}
117134
}
118-
return check(dist, left, hour) ? left : -1;
135+
return l > m ? -1 : l;
119136
}
120137

121-
private boolean check(int[] dist, int speed, double hour) {
122-
double res = 0;
123-
for (int i = 0; i < dist.length; ++i) {
124-
double cost = dist[i] * 1.0 / speed;
125-
res += (i == dist.length - 1 ? cost : Math.ceil(cost));
138+
private boolean check(int[] dist, int v, double hour) {
139+
double s = 0;
140+
int n = dist.length;
141+
for (int i = 0; i < n; ++i) {
142+
double t = dist[i] * 1.0 / v;
143+
s += i == n - 1 ? t : Math.ceil(t);
126144
}
127-
return res <= hour;
145+
return s <= hour;
128146
}
129147
}
130148
```
@@ -135,25 +153,29 @@ class Solution {
135153
class Solution {
136154
public:
137155
int minSpeedOnTime(vector<int>& dist, double hour) {
138-
int left = 1, right = 1e7;
139-
while (left < right) {
140-
int mid = (left + right) >> 1;
141-
if (check(dist, mid, hour)) {
142-
right = mid;
156+
if (dist.size() > ceil(hour)) {
157+
return -1;
158+
}
159+
const int m = 1e7;
160+
int l = 1, r = m + 1;
161+
int n = dist.size();
162+
auto check = [&](int v) {
163+
double s = 0;
164+
for (int i = 0; i < n; ++i) {
165+
double t = dist[i] * 1.0 / v;
166+
s += i == n - 1 ? t : ceil(t);
167+
}
168+
return s <= hour;
169+
};
170+
while (l < r) {
171+
int mid = (l + r) >> 1;
172+
if (check(mid)) {
173+
r = mid;
143174
} else {
144-
left = mid + 1;
175+
l = mid + 1;
145176
}
146177
}
147-
return check(dist, left, hour) ? left : -1;
148-
}
149-
150-
bool check(vector<int>& dist, int speed, double hour) {
151-
double res = 0;
152-
for (int i = 0; i < dist.size(); ++i) {
153-
double cost = dist[i] * 1.0 / speed;
154-
res += (i == dist.size() - 1 ? cost : ceil(cost));
155-
}
156-
return res <= hour;
178+
return l > m ? -1 : l;
157179
}
158180
};
159181
```
@@ -162,21 +184,58 @@ public:
162184
163185
```go
164186
func minSpeedOnTime(dist []int, hour float64) int {
187+
if float64(len(dist)) > math.Ceil(hour) {
188+
return -1
189+
}
190+
const m int = 1e7
165191
n := len(dist)
166-
const mx int = 1e7
167-
x := sort.Search(mx, func(s int) bool {
168-
s++
169-
var cost float64
170-
for _, v := range dist[:n-1] {
171-
cost += math.Ceil(float64(v) / float64(s))
192+
ans := sort.Search(m+1, func(v int) bool {
193+
v++
194+
s := 0.0
195+
for i, d := range dist {
196+
t := float64(d) / float64(v)
197+
if i == n-1 {
198+
s += t
199+
} else {
200+
s += math.Ceil(t)
201+
}
172202
}
173-
cost += float64(dist[n-1]) / float64(s)
174-
return cost <= hour
175-
})
176-
if x == mx {
203+
return s <= hour
204+
}) + 1
205+
if ans > m {
177206
return -1
178207
}
179-
return x + 1
208+
return ans
209+
}
210+
```
211+
212+
#### TypeScript
213+
214+
```ts
215+
function minSpeedOnTime(dist: number[], hour: number): number {
216+
if (dist.length > Math.ceil(hour)) {
217+
return -1;
218+
}
219+
const n = dist.length;
220+
const m = 10 ** 7;
221+
const check = (v: number): boolean => {
222+
let s = 0;
223+
for (let i = 0; i < n; ++i) {
224+
const t = dist[i] / v;
225+
s += i === n - 1 ? t : Math.ceil(t);
226+
}
227+
return s <= hour;
228+
};
229+
let [l, r] = [1, m + 1];
230+
while (l < r) {
231+
const mid = (l + r) >> 1;
232+
if (check(mid)) {
233+
r = mid;
234+
} else {
235+
l = mid + 1;
236+
}
237+
}
238+
return l > m ? -1 : l;
180239
}
181240
```
182241

@@ -185,35 +244,33 @@ func minSpeedOnTime(dist []int, hour float64) int {
185244
```rust
186245
impl Solution {
187246
pub fn min_speed_on_time(dist: Vec<i32>, hour: f64) -> i32 {
247+
if dist.len() as f64 > hour.ceil() {
248+
return -1;
249+
}
250+
const M: i32 = 10_000_000;
251+
let (mut l, mut r) = (1, M + 1);
188252
let n = dist.len();
189-
190-
let check = |speed| {
191-
let mut cur = 0.0;
192-
for (i, &d) in dist.iter().enumerate() {
193-
if i == n - 1 {
194-
cur += (d as f64) / (speed as f64);
195-
} else {
196-
cur += ((d as f64) / (speed as f64)).ceil();
197-
}
253+
let check = |v: i32| -> bool {
254+
let mut s = 0.0;
255+
for i in 0..n {
256+
let t = dist[i] as f64 / v as f64;
257+
s += if i == n - 1 { t } else { t.ceil() };
198258
}
199-
cur <= hour
259+
s <= hour
200260
};
201-
202-
let mut left = 1;
203-
let mut right = 1e7 as i32;
204-
while left < right {
205-
let mid = left + (right - left) / 2;
206-
if !check(mid) {
207-
left = mid + 1;
261+
while l < r {
262+
let mid = (l + r) / 2;
263+
if check(mid) {
264+
r = mid;
208265
} else {
209-
right = mid;
266+
l = mid + 1;
210267
}
211268
}
212-
213-
if check(left) {
214-
return left;
269+
if l > M {
270+
-1
271+
} else {
272+
l
215273
}
216-
-1
217274
}
218275
}
219276
```
@@ -227,63 +284,30 @@ impl Solution {
227284
* @return {number}
228285
*/
229286
var minSpeedOnTime = function (dist, hour) {
230-
if (dist.length > Math.ceil(hour)) return -1;
231-
let left = 1,
232-
right = 10 ** 7;
233-
while (left < right) {
234-
let mid = (left + right) >> 1;
235-
if (arriveOnTime(dist, mid, hour)) {
236-
right = mid;
237-
} else {
238-
left = mid + 1;
239-
}
287+
if (dist.length > Math.ceil(hour)) {
288+
return -1;
240289
}
241-
return left;
242-
};
243-
244-
function arriveOnTime(dist, speed, hour) {
245-
let res = 0.0;
246-
let n = dist.length;
247-
for (let i = 0; i < n; i++) {
248-
let cost = dist[i] / speed;
249-
if (i != n - 1) {
250-
cost = Math.ceil(cost);
251-
}
252-
res += cost;
253-
}
254-
return res <= hour;
255-
}
256-
```
257-
258-
#### TypeScript
259-
260-
```ts
261-
function minSpeedOnTime(dist: number[], hour: number): number {
262-
if (dist.length > Math.ceil(hour)) return -1;
263-
264-
const check = (speed: number) => {
265-
const n = dist.length;
266-
let time = 0;
267-
268-
for (let i = 0; i < n; i++) {
269-
const t = dist[i] / speed;
270-
time += i === n - 1 ? t : Math.ceil(t);
290+
const n = dist.length;
291+
const m = 10 ** 7;
292+
const check = v => {
293+
let s = 0;
294+
for (let i = 0; i < n; ++i) {
295+
const t = dist[i] / v;
296+
s += i === n - 1 ? t : Math.ceil(t);
271297
}
272-
273-
return hour >= time;
298+
return s <= hour;
274299
};
275-
276-
const max = 10 ** 7;
277-
let [l, r] = [1, max];
278-
279-
while (l <= r) {
280-
const i = (l + r) >> 1;
281-
if (check(i)) r = i - 1;
282-
else l = i + 1;
300+
let [l, r] = [1, m + 1];
301+
while (l < r) {
302+
const mid = (l + r) >> 1;
303+
if (check(mid)) {
304+
r = mid;
305+
} else {
306+
l = mid + 1;
307+
}
283308
}
284-
285-
return l <= max ? l : -1;
286-
}
309+
return l > m ? -1 : l;
310+
};
287311
```
288312

289313
<!-- tabs:end -->

0 commit comments

Comments
 (0)