81
81
82
82
<!-- solution:start -->
83
83
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)$.
85
95
86
96
<!-- tabs:start -->
87
97
@@ -90,12 +100,15 @@ tags:
90
100
``` python
91
101
class Solution :
92
102
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
95
105
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
98
109
110
+ if len (dist) > ceil(hour):
111
+ return - 1
99
112
r = 10 ** 7 + 1
100
113
ans = bisect_left(range (1 , r), True , key = check) + 1
101
114
return - 1 if ans == r else ans
@@ -106,25 +119,30 @@ class Solution:
106
119
``` java
107
120
class Solution {
108
121
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 ;
112
129
if (check(dist, mid, hour)) {
113
- right = mid;
130
+ r = mid;
114
131
} else {
115
- left = mid + 1 ;
132
+ l = mid + 1 ;
116
133
}
117
134
}
118
- return check(dist, left, hour) ? left : - 1 ;
135
+ return l > m ? - 1 : l ;
119
136
}
120
137
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);
126
144
}
127
- return res <= hour;
145
+ return s <= hour;
128
146
}
129
147
}
130
148
```
@@ -135,25 +153,29 @@ class Solution {
135
153
class Solution {
136
154
public:
137
155
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;
143
174
} else {
144
- left = mid + 1;
175
+ l = mid + 1;
145
176
}
146
177
}
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;
157
179
}
158
180
};
159
181
```
@@ -162,21 +184,58 @@ public:
162
184
163
185
```go
164
186
func minSpeedOnTime(dist []int, hour float64) int {
187
+ if float64(len(dist)) > math.Ceil(hour) {
188
+ return -1
189
+ }
190
+ const m int = 1e7
165
191
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
+ }
172
202
}
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 {
177
206
return -1
178
207
}
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 ;
180
239
}
181
240
```
182
241
@@ -185,35 +244,33 @@ func minSpeedOnTime(dist []int, hour float64) int {
185
244
``` rust
186
245
impl Solution {
187
246
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 );
188
252
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 () };
198
258
}
199
- cur <= hour
259
+ s <= hour
200
260
};
201
-
202
- let mut left = 1 ;
203
- let mut right = 1e 7 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 ;
208
265
} else {
209
- right = mid ;
266
+ l = mid + 1 ;
210
267
}
211
268
}
212
-
213
- if check (left ) {
214
- return left ;
269
+ if l > M {
270
+ - 1
271
+ } else {
272
+ l
215
273
}
216
- - 1
217
274
}
218
275
}
219
276
```
@@ -227,63 +284,30 @@ impl Solution {
227
284
* @return {number}
228
285
*/
229
286
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 ;
240
289
}
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);
271
297
}
272
-
273
- return hour >= time ;
298
+ return s <= hour;
274
299
};
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
+ }
283
308
}
284
-
285
- return l <= max ? l : - 1 ;
286
- }
309
+ return l > m ? - 1 : l;
310
+ };
287
311
```
288
312
289
313
<!-- tabs: end -->
0 commit comments