Skip to content

Commit 862740e

Browse files
authored
feat: add solutions to lc problem: No.0630 (doocs#1597)
No.0630.Course Schedule III
1 parent b7cadd1 commit 862740e

File tree

7 files changed

+185
-166
lines changed

7 files changed

+185
-166
lines changed

solution/0600-0699/0630.Course Schedule III/README.md

Lines changed: 58 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,15 @@
5353

5454
<!-- 这里可写通用的实现逻辑 -->
5555

56-
贪心 + 优先队列
56+
**方法一:贪心 + 优先队列(大根堆)**
5757

58-
先根据「结束时间」对 `courses` 升序排列,从前往后考虑每个课程,过程中维护一个总时长 s,对于某个课程 `courses[i]` 而言,根据如果学习该课程,是否满足「最晚完成时间」条件进行讨论:
58+
我们可以按照课程的结束时间进行升序排序,每次选择结束时间最早的课程进行上课。
5959

60-
- 学习该课程后,满足「最晚完成时间」要求,即 s + `courses[i][0]` <= `courses[i][1]`,则进行学习;
61-
- 学习该课程后,不满足「最晚完成时间」要求,此时从过往学习的课程中找出「持续时间」最长的课程进行「回退」操作(这个持续时长最长的课程也有可能是当前课程)。
60+
如果已选择的课程的总时间 $s$ 超过了当前课程的结束时间 $last$,那么我们就将此前选择的课程中耗时最长的课程去掉,直到能够满足当前课程的结束时间为止。这里我们使用一个优先队列(大根堆) $pq$ 来维护当前已经选择的课程的耗时,每次我们都从优先队列中取出耗时最长的课程进行去除。
61+
62+
最后,优先队列中的元素个数即为我们能够选择的课程数目。
63+
64+
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是课程数目。
6265

6366
<!-- tabs:start -->
6467

@@ -72,10 +75,10 @@ class Solution:
7275
courses.sort(key=lambda x: x[1])
7376
pq = []
7477
s = 0
75-
for d, e in courses:
76-
heappush(pq, -d)
77-
s += d
78-
if s > e:
78+
for duration, last in courses:
79+
heappush(pq, -duration)
80+
s += duration
81+
while s > last:
7982
s += heappop(pq)
8083
return len(pq)
8184
```
@@ -87,14 +90,14 @@ class Solution:
8790
```java
8891
class Solution {
8992
public int scheduleCourse(int[][] courses) {
90-
Arrays.sort(courses, Comparator.comparingInt(a -> a[1]));
93+
Arrays.sort(courses, (a, b) -> a[1] - b[1]);
9194
PriorityQueue<Integer> pq = new PriorityQueue<>((a, b) -> b - a);
9295
int s = 0;
93-
for (int[] course : courses) {
94-
int duration = course[0], lastDay = course[1];
96+
for (var e : courses) {
97+
int duration = e[0], last = e[1];
9598
pq.offer(duration);
9699
s += duration;
97-
if (s > lastDay) {
100+
while (s > last) {
98101
s -= pq.poll();
99102
}
100103
}
@@ -109,16 +112,16 @@ class Solution {
109112
class Solution {
110113
public:
111114
int scheduleCourse(vector<vector<int>>& courses) {
112-
sort(courses.begin(), courses.end(), [](const auto& c0, const auto& c1) {
113-
return c0[1] < c1[1];
115+
sort(courses.begin(), courses.end(), [](const vector<int>& a, const vector<int>& b) {
116+
return a[1] < b[1];
114117
});
115-
int s = 0;
116118
priority_queue<int> pq;
117-
for (auto& course : courses) {
118-
int d = course[0], e = course[1];
119-
pq.push(d);
120-
s += d;
121-
if (s > e) {
119+
int s = 0;
120+
for (auto& e : courses) {
121+
int duration = e[0], last = e[1];
122+
pq.push(duration);
123+
s += duration;
124+
while (s > last) {
122125
s -= pq.top();
123126
pq.pop();
124127
}
@@ -132,42 +135,49 @@ public:
132135
133136
```go
134137
func scheduleCourse(courses [][]int) int {
135-
sort.Slice(courses, func(i, j int) bool {
136-
return courses[i][1] < courses[j][1]
137-
})
138-
139-
h := &Heap{}
138+
sort.Slice(courses, func(i, j int) bool { return courses[i][1] < courses[j][1] })
139+
pq := &hp{}
140140
s := 0
141-
for _, course := range courses {
142-
if d := course[0]; s+d <= course[1] {
143-
s += d
144-
heap.Push(h, d)
145-
} else if h.Len() > 0 && d < h.IntSlice[0] {
146-
s += d - h.IntSlice[0]
147-
h.IntSlice[0] = d
148-
heap.Fix(h, 0)
141+
for _, e := range courses {
142+
duration, last := e[0], e[1]
143+
s += duration
144+
pq.push(duration)
145+
for s > last {
146+
s -= pq.pop()
149147
}
150148
}
151-
return h.Len()
152-
}
153-
154-
type Heap struct {
155-
sort.IntSlice
149+
return pq.Len()
156150
}
157151
158-
func (h Heap) Less(i, j int) bool {
159-
return h.IntSlice[i] > h.IntSlice[j]
160-
}
161-
162-
func (h *Heap) Push(x interface{}) {
163-
h.IntSlice = append(h.IntSlice, x.(int))
164-
}
152+
type hp struct{ sort.IntSlice }
165153
166-
func (h *Heap) Pop() interface{} {
154+
func (h hp) Less(i, j int) bool { return h.IntSlice[i] > h.IntSlice[j] }
155+
func (h *hp) Push(v any) { h.IntSlice = append(h.IntSlice, v.(int)) }
156+
func (h *hp) Pop() any {
167157
a := h.IntSlice
168-
x := a[len(a)-1]
158+
v := a[len(a)-1]
169159
h.IntSlice = a[:len(a)-1]
170-
return x
160+
return v
161+
}
162+
func (h *hp) push(v int) { heap.Push(h, v) }
163+
func (h *hp) pop() int { return heap.Pop(h).(int) }
164+
```
165+
166+
### **TypeScript**
167+
168+
```ts
169+
function scheduleCourse(courses: number[][]): number {
170+
courses.sort((a, b) => a[1] - b[1]);
171+
const pq = new MaxPriorityQueue();
172+
let s = 0;
173+
for (const [duration, last] of courses) {
174+
pq.enqueue(duration);
175+
s += duration;
176+
while (s > last) {
177+
s -= pq.dequeue().element;
178+
}
179+
}
180+
return pq.size();
171181
}
172182
```
173183

solution/0600-0699/0630.Course Schedule III/README_EN.md

Lines changed: 51 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,10 @@ class Solution:
5858
courses.sort(key=lambda x: x[1])
5959
pq = []
6060
s = 0
61-
for d, e in courses:
62-
heappush(pq, -d)
63-
s += d
64-
if s > e:
61+
for duration, last in courses:
62+
heappush(pq, -duration)
63+
s += duration
64+
while s > last:
6565
s += heappop(pq)
6666
return len(pq)
6767
```
@@ -71,14 +71,14 @@ class Solution:
7171
```java
7272
class Solution {
7373
public int scheduleCourse(int[][] courses) {
74-
Arrays.sort(courses, Comparator.comparingInt(a -> a[1]));
74+
Arrays.sort(courses, (a, b) -> a[1] - b[1]);
7575
PriorityQueue<Integer> pq = new PriorityQueue<>((a, b) -> b - a);
7676
int s = 0;
77-
for (int[] course : courses) {
78-
int duration = course[0], lastDay = course[1];
77+
for (var e : courses) {
78+
int duration = e[0], last = e[1];
7979
pq.offer(duration);
8080
s += duration;
81-
if (s > lastDay) {
81+
while (s > last) {
8282
s -= pq.poll();
8383
}
8484
}
@@ -93,16 +93,16 @@ class Solution {
9393
class Solution {
9494
public:
9595
int scheduleCourse(vector<vector<int>>& courses) {
96-
sort(courses.begin(), courses.end(), [](const auto& c0, const auto& c1) {
97-
return c0[1] < c1[1];
96+
sort(courses.begin(), courses.end(), [](const vector<int>& a, const vector<int>& b) {
97+
return a[1] < b[1];
9898
});
99-
int s = 0;
10099
priority_queue<int> pq;
101-
for (auto& course : courses) {
102-
int d = course[0], e = course[1];
103-
pq.push(d);
104-
s += d;
105-
if (s > e) {
100+
int s = 0;
101+
for (auto& e : courses) {
102+
int duration = e[0], last = e[1];
103+
pq.push(duration);
104+
s += duration;
105+
while (s > last) {
106106
s -= pq.top();
107107
pq.pop();
108108
}
@@ -116,42 +116,49 @@ public:
116116
117117
```go
118118
func scheduleCourse(courses [][]int) int {
119-
sort.Slice(courses, func(i, j int) bool {
120-
return courses[i][1] < courses[j][1]
121-
})
122-
123-
h := &Heap{}
119+
sort.Slice(courses, func(i, j int) bool { return courses[i][1] < courses[j][1] })
120+
pq := &hp{}
124121
s := 0
125-
for _, course := range courses {
126-
if d := course[0]; s+d <= course[1] {
127-
s += d
128-
heap.Push(h, d)
129-
} else if h.Len() > 0 && d < h.IntSlice[0] {
130-
s += d - h.IntSlice[0]
131-
h.IntSlice[0] = d
132-
heap.Fix(h, 0)
122+
for _, e := range courses {
123+
duration, last := e[0], e[1]
124+
s += duration
125+
pq.push(duration)
126+
for s > last {
127+
s -= pq.pop()
133128
}
134129
}
135-
return h.Len()
136-
}
137-
138-
type Heap struct {
139-
sort.IntSlice
140-
}
141-
142-
func (h Heap) Less(i, j int) bool {
143-
return h.IntSlice[i] > h.IntSlice[j]
130+
return pq.Len()
144131
}
145132
146-
func (h *Heap) Push(x interface{}) {
147-
h.IntSlice = append(h.IntSlice, x.(int))
148-
}
133+
type hp struct{ sort.IntSlice }
149134
150-
func (h *Heap) Pop() interface{} {
135+
func (h hp) Less(i, j int) bool { return h.IntSlice[i] > h.IntSlice[j] }
136+
func (h *hp) Push(v any) { h.IntSlice = append(h.IntSlice, v.(int)) }
137+
func (h *hp) Pop() any {
151138
a := h.IntSlice
152-
x := a[len(a)-1]
139+
v := a[len(a)-1]
153140
h.IntSlice = a[:len(a)-1]
154-
return x
141+
return v
142+
}
143+
func (h *hp) push(v int) { heap.Push(h, v) }
144+
func (h *hp) pop() int { return heap.Pop(h).(int) }
145+
```
146+
147+
### **TypeScript**
148+
149+
```ts
150+
function scheduleCourse(courses: number[][]): number {
151+
courses.sort((a, b) => a[1] - b[1]);
152+
const pq = new MaxPriorityQueue();
153+
let s = 0;
154+
for (const [duration, last] of courses) {
155+
pq.enqueue(duration);
156+
s += duration;
157+
while (s > last) {
158+
s -= pq.dequeue().element;
159+
}
160+
}
161+
return pq.size();
155162
}
156163
```
157164

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
class Solution {
2-
public:
3-
int scheduleCourse(vector<vector<int>>& courses) {
4-
sort(courses.begin(), courses.end(), [](const auto& c0, const auto& c1) {
5-
return c0[1] < c1[1];
6-
});
7-
int s = 0;
8-
priority_queue<int> pq;
9-
for (auto& course : courses) {
10-
int d = course[0], e = course[1];
11-
pq.push(d);
12-
s += d;
13-
if (s > e) {
14-
s -= pq.top();
15-
pq.pop();
16-
}
17-
}
18-
return pq.size();
19-
}
1+
class Solution {
2+
public:
3+
int scheduleCourse(vector<vector<int>>& courses) {
4+
sort(courses.begin(), courses.end(), [](const vector<int>& a, const vector<int>& b) {
5+
return a[1] < b[1];
6+
});
7+
priority_queue<int> pq;
8+
int s = 0;
9+
for (auto& e : courses) {
10+
int duration = e[0], last = e[1];
11+
pq.push(duration);
12+
s += duration;
13+
while (s > last) {
14+
s -= pq.top();
15+
pq.pop();
16+
}
17+
}
18+
return pq.size();
19+
}
2020
};
Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,27 @@
11
func scheduleCourse(courses [][]int) int {
2-
sort.Slice(courses, func(i, j int) bool {
3-
return courses[i][1] < courses[j][1]
4-
})
5-
6-
h := &Heap{}
2+
sort.Slice(courses, func(i, j int) bool { return courses[i][1] < courses[j][1] })
3+
pq := &hp{}
74
s := 0
8-
for _, course := range courses {
9-
if d := course[0]; s+d <= course[1] {
10-
s += d
11-
heap.Push(h, d)
12-
} else if h.Len() > 0 && d < h.IntSlice[0] {
13-
s += d - h.IntSlice[0]
14-
h.IntSlice[0] = d
15-
heap.Fix(h, 0)
5+
for _, e := range courses {
6+
duration, last := e[0], e[1]
7+
s += duration
8+
pq.push(duration)
9+
for s > last {
10+
s -= pq.pop()
1611
}
1712
}
18-
return h.Len()
19-
}
20-
21-
type Heap struct {
22-
sort.IntSlice
13+
return pq.Len()
2314
}
2415

25-
func (h Heap) Less(i, j int) bool {
26-
return h.IntSlice[i] > h.IntSlice[j]
27-
}
16+
type hp struct{ sort.IntSlice }
2817

29-
func (h *Heap) Push(x interface{}) {
30-
h.IntSlice = append(h.IntSlice, x.(int))
31-
}
32-
33-
func (h *Heap) Pop() interface{} {
18+
func (h hp) Less(i, j int) bool { return h.IntSlice[i] > h.IntSlice[j] }
19+
func (h *hp) Push(v any) { h.IntSlice = append(h.IntSlice, v.(int)) }
20+
func (h *hp) Pop() any {
3421
a := h.IntSlice
35-
x := a[len(a)-1]
22+
v := a[len(a)-1]
3623
h.IntSlice = a[:len(a)-1]
37-
return x
38-
}
24+
return v
25+
}
26+
func (h *hp) push(v int) { heap.Push(h, v) }
27+
func (h *hp) pop() int { return heap.Pop(h).(int) }

0 commit comments

Comments
 (0)