Skip to content

Commit e53ead0

Browse files
committed
feat: add solutions to lcp problem: No.12
LCP 12.小张刷题计划
1 parent e05f3f6 commit e53ead0

File tree

5 files changed

+229
-1
lines changed

5 files changed

+229
-1
lines changed

lcp/LCP 12. 小张刷题计划/README.md

+125-1
Original file line numberDiff line numberDiff line change
@@ -44,22 +44,146 @@
4444

4545
<!-- 这里可写通用的实现逻辑 -->
4646

47+
**方法一:贪心 + 二分查找**
48+
49+
我们可以将题意转换为,将题目最多分成 $m$ 组,每一组去掉最大值后不超过 $T$ ,求最小的满足条件的 $T$。
50+
51+
我们定义二分查找的左边界 $left=0$,右边界 $right=\sum_{i=0}^{n-1}time[i]$,二分查找的目标值为 $T$。
52+
53+
我们定义函数 $check(T)$,表示是否存在一种分组方案,使得每一组去掉最大值后不超过 $T$,并且分组数不超过 $m$。
54+
55+
我们可以用贪心的方法来判断是否存在这样的分组方案。我们从左到右遍历题目,将题目耗时加入当前总耗时 $s$,并更新当前分组的最大值 $mx$。如果当前总耗时 $s$ 减去当前分组的最大值 $mx$ 大于 $T$,则将当前题目作为新的分组的第一题,更新 $s$ 和 $mx$。继续遍历题目,直到遍历完所有题目。如果分组数不超过 $m$,则说明存在这样的分组方案,返回 $true$,否则返回 $false$。
56+
57+
时间复杂度 $O(n \times \log S)$,空间复杂度 $O(1)$。其中 $n$ 和 $S$ 分别为题目数量和题目总耗时。
58+
4759
<!-- tabs:start -->
4860

4961
### **Python3**
5062

5163
<!-- 这里可写当前语言的特殊实现逻辑 -->
5264

5365
```python
54-
66+
class Solution:
67+
def minTime(self, time: List[int], m: int) -> int:
68+
def check(t):
69+
s = mx = 0
70+
d = 1
71+
for x in time:
72+
s += x
73+
mx = max(mx, x)
74+
if s - mx > t:
75+
d += 1
76+
s = mx = x
77+
return d <= m
78+
79+
return bisect_left(range(sum(time)), True, key=check)
5580
```
5681

5782
### **Java**
5883

5984
<!-- 这里可写当前语言的特殊实现逻辑 -->
6085

6186
```java
87+
class Solution {
88+
public int minTime(int[] time, int m) {
89+
int left = 0, right = 0;
90+
for (int x : time) {
91+
right += x;
92+
}
93+
while (left < right) {
94+
int mid = (left + right) >> 1;
95+
if (check(mid, time, m)) {
96+
right = mid;
97+
} else {
98+
left = mid + 1;
99+
}
100+
}
101+
return left;
102+
}
103+
104+
private boolean check(int t, int[] time, int m) {
105+
int s = 0, mx = 0;
106+
int d = 1;
107+
for (int x : time) {
108+
s += x;
109+
mx = Math.max(mx, x);
110+
if (s - mx > t) {
111+
s = x;
112+
mx = x;
113+
++d;
114+
}
115+
}
116+
return d <= m;
117+
}
118+
}
119+
```
120+
121+
### **C++**
122+
123+
```cpp
124+
class Solution {
125+
public:
126+
int minTime(vector<int>& time, int m) {
127+
int left = 0, right = 0;
128+
for (int x : time) {
129+
right += x;
130+
}
131+
auto check = [&](int t) -> bool {
132+
int s = 0, mx = 0;
133+
int d = 1;
134+
for (int x : time) {
135+
s += x;
136+
mx = max(mx, x);
137+
if (s - mx > t) {
138+
s = x;
139+
mx = x;
140+
++d;
141+
}
142+
}
143+
return d <= m;
144+
};
145+
while (left < right) {
146+
int mid = (left + right) >> 1;
147+
if (check(mid)) {
148+
right = mid;
149+
} else {
150+
left = mid + 1;
151+
}
152+
}
153+
return left;
154+
}
155+
};
156+
```
62157
158+
### **Go**
159+
160+
```go
161+
func minTime(time []int, m int) int {
162+
right := 0
163+
for _, x := range time {
164+
right += x
165+
}
166+
return sort.Search(right, func(t int) bool {
167+
s, mx := 0, 0
168+
d := 1
169+
for _, x := range time {
170+
s += x
171+
mx = max(mx, x)
172+
if s-mx > t {
173+
s, mx = x, x
174+
d++
175+
}
176+
}
177+
return d <= m
178+
})
179+
}
180+
181+
func max(a, b int) int {
182+
if a > b {
183+
return a
184+
}
185+
return b
186+
}
63187
```
64188

65189
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
class Solution {
2+
public:
3+
int minTime(vector<int>& time, int m) {
4+
int left = 0, right = 0;
5+
for (int x : time) {
6+
right += x;
7+
}
8+
auto check = [&](int t) -> bool {
9+
int s = 0, mx = 0;
10+
int d = 1;
11+
for (int x : time) {
12+
s += x;
13+
mx = max(mx, x);
14+
if (s - mx > t) {
15+
s = x;
16+
mx = x;
17+
++d;
18+
}
19+
}
20+
return d <= m;
21+
};
22+
while (left < right) {
23+
int mid = (left + right) >> 1;
24+
if (check(mid)) {
25+
right = mid;
26+
} else {
27+
left = mid + 1;
28+
}
29+
}
30+
return left;
31+
}
32+
};
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
func minTime(time []int, m int) int {
2+
right := 0
3+
for _, x := range time {
4+
right += x
5+
}
6+
return sort.Search(right, func(t int) bool {
7+
s, mx := 0, 0
8+
d := 1
9+
for _, x := range time {
10+
s += x
11+
mx = max(mx, x)
12+
if s-mx > t {
13+
s, mx = x, x
14+
d++
15+
}
16+
}
17+
return d <= m
18+
})
19+
}
20+
21+
func max(a, b int) int {
22+
if a > b {
23+
return a
24+
}
25+
return b
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
class Solution {
2+
public int minTime(int[] time, int m) {
3+
int left = 0, right = 0;
4+
for (int x : time) {
5+
right += x;
6+
}
7+
while (left < right) {
8+
int mid = (left + right) >> 1;
9+
if (check(mid, time, m)) {
10+
right = mid;
11+
} else {
12+
left = mid + 1;
13+
}
14+
}
15+
return left;
16+
}
17+
18+
private boolean check(int t, int[] time, int m) {
19+
int s = 0, mx = 0;
20+
int d = 1;
21+
for (int x : time) {
22+
s += x;
23+
mx = Math.max(mx, x);
24+
if (s - mx > t) {
25+
s = x;
26+
mx = x;
27+
++d;
28+
}
29+
}
30+
return d <= m;
31+
}
32+
}
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
class Solution:
2+
def minTime(self, time: List[int], m: int) -> int:
3+
def check(t):
4+
s = mx = 0
5+
d = 1
6+
for x in time:
7+
s += x
8+
mx = max(mx, x)
9+
if s - mx > t:
10+
d += 1
11+
s = mx = x
12+
return d <= m
13+
14+
return bisect_left(range(sum(time)), True, key=check)

0 commit comments

Comments
 (0)