题目
解题思路
这道题可谓是深有感触,最近期末考试正好正在进行中,我的复习(预习)也正在进行中,我是一个经常逃课的孩子(…)
大家在期末复习的时候怎么进行先后复习的呢?
我们肯定是先复习距离考试时间最近的科目啊。而这道题给的就是每次只能处理一个科目的复习,中间不间断,然后给了你每个科目的复习时间。这就导致如果有些科目虽然是距离DDL时间近,但如果我们复习完它之后就会导致其他的DDL远一些的无法完成复习,
具体举例子如下:
假设 duration
数组是这样的 大学物理 [2, 4]
高等数学 [5, 7]
线性代数 [3, 3]
那么,按照策略,我们会先尝试修读线性代数。 然后尝试修读大学物理,这个时候我们发现竟然修了线性代数之后就修不了大学物理了;只能放弃;转而修高等数学发现也没有足够的时间了。
那合理的做法是什么呢? 就是我们这个时候需要放弃线性代数,因为线性代数和大学物理的权重是没有区别的,既然两者只能修一门,我们应该让当前累计花费的时间更少。大学物理虽然ddl比线性代数更晚,但它修读的时间也更短,如果已经要放弃一门课了,我们会放弃修读时间更长的。
总结:
- 我们先复习DDL时间比较近的。
- 如果出现复习时间超出DDL,则需要进行优化,放弃之前选择过的需要花时间最多的科目,用当前这个进行替代,能减少当前耗时!(这个的前提条件建立在优先选择DDL近的,因为这样按照时间排序后,一旦产生超过的,只要和前面最大的进行替换,耗时肯定会变得更小,所以就不会超过DDL了)
解题代码
根据解题思路得出代码的书写思路:
- 优先复习DDL时间近的–>利用DDL从小到大对其进行排序。
- 超出DDL时的替换过程–>利用优先队列进行操作即可。
cpp解法
class Solution {
public:
int scheduleCourse(vector<vector<int>>& courses) {
sort(courses.begin(), courses.end(), [](const auto& a, const auto& b) {
return a[1] < b [1];});
priority_queue<int> q;
int day = 0;
for (const auto& c: courses) {
if (day + c[0] <= c[1]) {
day += c[0];
q.push(c[0]);
continue;
}
if (!q.empty() && q.top() > c[0]) {
day -= q.top();
day += c[0];
q.pop();
q.push(c[0]);
}
}
return q.size();
}
};
go语言有点麻烦,还需要实现一些接口才能使用Heap
go语言
func scheduleCourse(courses [][]int) int {
sort.Slice(courses, func(i, j int) bool {
return courses[i][1] < courses[j][1]
})
h := &IntHeap{
}
total := 0 // 优先队列中所有课程的总时间
for _, course := range courses {
if t := course[0]; total+t <= course[1] {
total += t
heap.Push(h, t)
} else if h.Len() > 0 && t < (*h)[0] {
total += t - (*h)[0]
heap.Pop(h)
heap.Push(h,t)
}
}
return h.Len()
}
type IntHeap []int // 定义一个类型
func (h IntHeap) Len() int {
return len(h) } // 绑定len方法,返回长度
func (h IntHeap) Less(i, j int) bool {
// 绑定less方法
return h[i] > h[j] // 如果h[i]<h[j]生成的就是小根堆,如果h[i]>h[j]生成的就是大根堆
}
func (h IntHeap) Swap(i, j int) {
// 绑定swap方法,交换两个元素位置
h[i], h[j] = h[j], h[i]
}
func (h *IntHeap) Pop() interface{
} {
// 绑定pop方法,从最后拿出一个元素并返回
old := *h
n := len(old)
x := old[n-1]
*h = old[0 : n-1]
return x
}
func (h *IntHeap) Push(x interface{
}) {
// 绑定push方法,插入新元素
*h = append(*h, x.(int))
}