Skip to content

Commit 37fb98d

Browse files
committedMar 3, 2022
feat: update solutions to lc problems: No.1870,1898
* No.1870.Minimum Speed to Arrive on Time * No.1898.Maximum Number of Removable Characters
1 parent 4c9533c commit 37fb98d

File tree

12 files changed

+376
-118
lines changed

12 files changed

+376
-118
lines changed
 

‎basic/searching/BinarySearch/README_EN.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ int search(int left, int right) {
2020
}
2121
```
2222

23-
### Template 1
23+
### Template 2
2424

2525
```java
2626
boolean check(int x) {}

‎solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/README.md

+47-2
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,54 @@
5151

5252
<!-- 这里可写通用的实现逻辑 -->
5353

54-
二分查找。
54+
二分查找。两遍二分,分别查找出左边界和右边界。
5555

56-
两遍二分,分别查找出左边界和右边界。
56+
模板 1:
57+
58+
```java
59+
boolean check(int x) {}
60+
61+
int search(int left, int right) {
62+
while (left < right) {
63+
int mid = (left + right) >> 1;
64+
if (check(mid)) {
65+
right = mid;
66+
} else {
67+
left = mid + 1;
68+
}
69+
}
70+
return left;
71+
}
72+
```
73+
74+
模板 2:
75+
76+
```java
77+
boolean check(int x) {}
78+
79+
int search(int left, int right) {
80+
while (left < right) {
81+
int mid = (left + right + 1) >> 1;
82+
if (check(mid)) {
83+
left = mid;
84+
} else {
85+
right = mid - 1;
86+
}
87+
}
88+
return left;
89+
}
90+
```
91+
92+
做二分题目时,可以按照以下步骤:
93+
94+
1. 写出循环条件:`while (left < right)`,注意是 `left < right`,而非 `left <= right`
95+
1. 循环体内,先无脑写出 `mid = (left + right) >> 1`
96+
1. 根据具体题目,实现 `check()` 函数(有时很简单的逻辑,可以不定义 `check`),想一下究竟要用 `right = mid`(模板 1) 还是 `left = mid`(模板 2);
97+
- 如果 `right = mid`,那么无脑写出 else 语句 `left = mid + 1`,并且不需要更改 mid 的计算,即保持 `mid = (left + right) >> 1`
98+
- 如果 `left = mid`,那么无脑写出 else 语句 `right = mid - 1`,并且在 mid 计算时补充 +1,即 `mid = (left + right + 1) >> 1`
99+
1. 循环结束时,left 与 right 相等。
100+
101+
注意,这两个模板的优点是始终保持答案位于二分区间内,二分结束条件对应的值恰好在答案所处的位置。 对于可能无解的情况,只要判断二分结束后的 left 或者 right 是否满足题意即可。
57102

58103
<!-- tabs:start -->
59104

‎solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/README_EN.md

+36
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,42 @@
3535

3636
Binary search.
3737

38+
Template 1:
39+
40+
```java
41+
boolean check(int x) {}
42+
43+
int search(int left, int right) {
44+
while (left < right) {
45+
int mid = (left + right) >> 1;
46+
if (check(mid)) {
47+
right = mid;
48+
} else {
49+
left = mid + 1;
50+
}
51+
}
52+
return left;
53+
}
54+
```
55+
56+
Template 2:
57+
58+
```java
59+
boolean check(int x) {}
60+
61+
int search(int left, int right) {
62+
while (left < right) {
63+
int mid = (left + right + 1) >> 1;
64+
if (check(mid)) {
65+
left = mid;
66+
} else {
67+
right = mid - 1;
68+
}
69+
}
70+
return left;
71+
}
72+
```
73+
3874
<!-- tabs:start -->
3975

4076
### **Python3**

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

+69-20
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,55 @@
7070

7171
以“二分”的方式枚举速度值,找到满足条件的最小速度。
7272

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+
73122
<!-- tabs:start -->
74123

75124
### **Python3**
@@ -79,7 +128,7 @@
79128
```python
80129
class Solution:
81130
def minSpeedOnTime(self, dist: List[int], hour: float) -> int:
82-
def arrive_on_time(speed):
131+
def check(speed):
83132
res = 0
84133
for i, d in enumerate(dist):
85134
res += (d / speed) if i == len(dist) - 1 else math.ceil(d / speed)
@@ -88,11 +137,11 @@ class Solution:
88137
left, right = 1, 10 ** 7
89138
while left < right:
90139
mid = (left + right) >> 1
91-
if arrive_on_time(mid):
140+
if check(mid):
92141
right = mid
93142
else:
94143
left = mid + 1
95-
return left if arrive_on_time(left) else -1
144+
return left if check(left) else -1
96145
```
97146

98147
### **Java**
@@ -105,16 +154,16 @@ class Solution {
105154
int left = 1, right = (int) 1e7;
106155
while (left < right) {
107156
int mid = (left + right) >> 1;
108-
if (arriveOnTime(dist, mid, hour)) {
157+
if (check(dist, mid, hour)) {
109158
right = mid;
110159
} else {
111160
left = mid + 1;
112161
}
113162
}
114-
return arriveOnTime(dist, left, hour) ? left : -1;
163+
return check(dist, left, hour) ? left : -1;
115164
}
116165

117-
private boolean arriveOnTime(int[] dist, int speed, double hour) {
166+
private boolean check(int[] dist, int speed, double hour) {
118167
double res = 0;
119168
for (int i = 0; i < dist.length; ++i) {
120169
double cost = dist[i] * 1.0 / speed;
@@ -134,16 +183,16 @@ public:
134183
int left = 1, right = 1e7;
135184
while (left < right) {
136185
int mid = (left + right) >> 1;
137-
if (arriveOnTime(dist, mid, hour)) {
186+
if (check(dist, mid, hour)) {
138187
right = mid;
139188
} else {
140189
left = mid + 1;
141190
}
142191
}
143-
return arriveOnTime(dist, left, hour) ? left : -1;
192+
return check(dist, left, hour) ? left : -1;
144193
}
145194

146-
bool arriveOnTime(vector<int>& dist, int speed, double hour) {
195+
bool check(vector<int>& dist, int speed, double hour) {
147196
double res = 0;
148197
for (int i = 0; i < dist.size(); ++i) {
149198
double cost = dist[i] * 1.0 / speed;
@@ -197,28 +246,28 @@ function arriveOnTime(dist, speed, hour) {
197246
func minSpeedOnTime(dist []int, hour float64) int {
198247
n := len(dist)
199248
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+
}
200258
for left < right {
201259
mid := (left + right) >> 1
202-
if arriveOnTime(dist, n, float64(mid), hour) {
260+
if check(float64(mid)) {
203261
right = mid
204262
} else {
205263
left = mid + 1
206264
}
207265
}
208-
if arriveOnTime(dist, n, float64(left), hour) {
266+
if check(float64(left)) {
209267
return left
210268
}
211269
return -1
212270
}
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-
}
222271
```
223272

224273
### **...**

0 commit comments

Comments
 (0)