70
70
71
71
以“二分”的方式枚举速度值,找到满足条件的最小速度。
72
72
73
+ 以下是二分查找的两个模板:
74
+
75
+ 模板 1:
76
+
77
+ ``` java
78
+ boolean check(int x) {}
79
+
80
+ int search(int left, int right) {
81
+ while (left < right) {
82
+ int mid = (left + right) >> 1 ;
83
+ if (check(mid)) {
84
+ right = mid;
85
+ } else {
86
+ left = mid + 1 ;
87
+ }
88
+ }
89
+ return left;
90
+ }
91
+ ```
92
+
93
+ 模板 2:
94
+
95
+ ``` java
96
+ boolean check(int x) {}
97
+
98
+ int search(int left, int right) {
99
+ while (left < right) {
100
+ int mid = (left + right + 1 ) >> 1 ;
101
+ if (check(mid)) {
102
+ left = mid;
103
+ } else {
104
+ right = mid - 1 ;
105
+ }
106
+ }
107
+ return left;
108
+ }
109
+ ```
110
+
111
+ 做二分题目时,可以按照以下步骤:
112
+
113
+ 1 . 写出循环条件:` while (left < right) ` ,注意是 ` left < right ` ,而非 ` left <= right ` ;
114
+ 1 . 循环体内,先无脑写出 ` mid = (left + right) >> 1 ` ;
115
+ 1 . 根据具体题目,实现 ` check() ` 函数(有时很简单的逻辑,可以不定义 ` check ` ),想一下究竟要用 ` right = mid ` (模板 1) 还是 ` left = mid ` (模板 2);
116
+ - 如果 ` right = mid ` ,那么无脑写出 else 语句 ` left = mid + 1 ` ,并且不需要更改 mid 的计算,即保持 ` mid = (left + right) >> 1 ` ;
117
+ - 如果 ` left = mid ` ,那么无脑写出 else 语句 ` right = mid - 1 ` ,并且在 mid 计算时补充 +1,即 ` mid = (left + right + 1) >> 1 ` 。
118
+ 1 . 循环结束时,left 与 right 相等。
119
+
120
+ 注意,这两个模板的优点是始终保持答案位于二分区间内,二分结束条件对应的值恰好在答案所处的位置。 对于可能无解的情况,只要判断二分结束后的 left 或者 right 是否满足题意即可。
121
+
73
122
<!-- tabs:start -->
74
123
75
124
### ** Python3**
79
128
``` python
80
129
class Solution :
81
130
def minSpeedOnTime (self , dist : List[int ], hour : float ) -> int :
82
- def arrive_on_time (speed ):
131
+ def check (speed ):
83
132
res = 0
84
133
for i, d in enumerate (dist):
85
134
res += (d / speed) if i == len (dist) - 1 else math.ceil(d / speed)
@@ -88,11 +137,11 @@ class Solution:
88
137
left, right = 1 , 10 ** 7
89
138
while left < right:
90
139
mid = (left + right) >> 1
91
- if arrive_on_time (mid):
140
+ if check (mid):
92
141
right = mid
93
142
else :
94
143
left = mid + 1
95
- return left if arrive_on_time (left) else - 1
144
+ return left if check (left) else - 1
96
145
```
97
146
98
147
### ** Java**
@@ -105,16 +154,16 @@ class Solution {
105
154
int left = 1 , right = (int ) 1e7 ;
106
155
while (left < right) {
107
156
int mid = (left + right) >> 1 ;
108
- if (arriveOnTime (dist, mid, hour)) {
157
+ if (check (dist, mid, hour)) {
109
158
right = mid;
110
159
} else {
111
160
left = mid + 1 ;
112
161
}
113
162
}
114
- return arriveOnTime (dist, left, hour) ? left : - 1 ;
163
+ return check (dist, left, hour) ? left : - 1 ;
115
164
}
116
165
117
- private boolean arriveOnTime (int [] dist , int speed , double hour ) {
166
+ private boolean check (int [] dist , int speed , double hour ) {
118
167
double res = 0 ;
119
168
for (int i = 0 ; i < dist. length; ++ i) {
120
169
double cost = dist[i] * 1.0 / speed;
@@ -134,16 +183,16 @@ public:
134
183
int left = 1, right = 1e7;
135
184
while (left < right) {
136
185
int mid = (left + right) >> 1;
137
- if (arriveOnTime (dist, mid, hour)) {
186
+ if (check (dist, mid, hour)) {
138
187
right = mid;
139
188
} else {
140
189
left = mid + 1;
141
190
}
142
191
}
143
- return arriveOnTime (dist, left, hour) ? left : -1;
192
+ return check (dist, left, hour) ? left : -1;
144
193
}
145
194
146
- bool arriveOnTime (vector<int>& dist, int speed, double hour) {
195
+ bool check (vector<int>& dist, int speed, double hour) {
147
196
double res = 0;
148
197
for (int i = 0; i < dist.size(); ++i) {
149
198
double cost = dist[i] * 1.0 / speed;
@@ -197,28 +246,28 @@ function arriveOnTime(dist, speed, hour) {
197
246
func minSpeedOnTime (dist []int , hour float64 ) int {
198
247
n := len (dist)
199
248
left , right := 1 , int (1e7 )
249
+ check := func (speed float64 ) bool {
250
+ var cost float64
251
+ for _ , v := range dist[:n-1 ] {
252
+ cost += math.Ceil (float64 (v) / speed)
253
+ }
254
+ cost += float64 (dist[n-1 ]) / speed
255
+ return cost <= hour
256
+
257
+ }
200
258
for left < right {
201
259
mid := (left + right) >> 1
202
- if arriveOnTime (dist, n, float64 (mid), hour ) {
260
+ if check ( float64 (mid)) {
203
261
right = mid
204
262
} else {
205
263
left = mid + 1
206
264
}
207
265
}
208
- if arriveOnTime (dist, n, float64 (left), hour ) {
266
+ if check ( float64 (left)) {
209
267
return left
210
268
}
211
269
return -1
212
270
}
213
-
214
- func arriveOnTime (dist []int , n int , speed , hour float64 ) bool {
215
- var cost float64
216
- for _ , v := range dist[:n-1 ] {
217
- cost += math.Ceil (float64 (v) / speed)
218
- }
219
- cost += float64 (dist[n-1 ]) / speed
220
- return cost <= hour
221
- }
222
271
```
223
272
224
273
### ** ...**
0 commit comments