Course Schedule
1
According to the problem description, it is easily to find that we need to use Topological Sort
to solve with the problem. Topological Sort is an easy algorithm. If a node without in-degree which means the node can be visited at any moment. If a node with one in-degree which means the node can be visited if and only if its father node has to be visited before it. So things are becoming easy. You can just keep a queue with all of the node without in-degree, and choose one from the queue at each time, then decrease the in-degree of nodes
which link with the node.
#include <vector>
#include <queue>
using namespace std;
class Solution {
public:
bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
vector<int> inDegree(numCourses, 0);
vector<vector<int>> son(numCourses);
for (int i = 0; i < prerequisites.size(); ++i) {
inDegree[prerequisites[i].first]++;
son[prerequisites[i].second].push_back(prerequisites[i].first);
}
queue<int> courseQueue;
int finishedCourse = 0;
for (int j = 0; j < numCourses; ++j) {
if (inDegree[j] == 0) { courseQueue.push(j); finishedCourse++; }
}
while (!courseQueue.empty()) {
int top = courseQueue.front();
courseQueue.pop();
for (int i = 0; i < son[top].size(); ++i) {
inDegree[son[top][i]]--;
if (inDegree[son[top][i]] == 0) {
finishedCourse++;
courseQueue.push(son[top][i]);
}
}
}
return finishedCourse == numCourses;
}
};
2
The same as before, you just need to record the feasible solution.
#include <vector>
#include <iostream>
#include <queue>
using namespace std;
class Solution {
public:
vector<int> findOrder(int numCourses, vector<pair<int, int>>& prerequisites) {
vector<int> inDegree(numCourses, 0);
vector<vector<int>> son(numCourses);
for (int i = 0; i < prerequisites.size(); ++i) {
inDegree[prerequisites[i].first]++;
son[prerequisites[i].second].push_back(prerequisites[i].first);
}
queue<int> courseQueue;
int finishedCourse = 0;
vector<int> ans;
for (int j = 0; j < numCourses; ++j) {
if (inDegree[j] == 0) { courseQueue.push(j); ans.push_back(j); finishedCourse++; }
}
while (!courseQueue.empty()) {
int top = courseQueue.front();
courseQueue.pop();
for (int i = 0; i < son[top].size(); ++i) {
inDegree[son[top][i]]--;
if (inDegree[son[top][i]] == 0) {
ans.push_back(son[top][i]);
finishedCourse++;
courseQueue.push(son[top][i]);
}
}
}
return finishedCourse == numCourses ? ans : vector<int>{};
}
};
3
Prove that:
condition:
d1 <= d2 <= d3 <= …. <= dm (after sorting)
to satisfy:
t1 <= d1
t1 + t2 <= d2
t1 + t2 + t3 <= d3
…..
t1 + t2 + t3 + …. + tm <= dm
Assume that we have t1 + t2 + t3 <= d3, but t1 + t2 + t3 + t4 > d4, then we need to remove the highest value of t[1:4], if it is t3, after that because t3 > t4, d3 < d4, t1 + t2 + t3 <= d3, we will absolutely conclude that t1 + t2 + t4 <= d3 <= d4. And we can find that 3 is the local optimal solution.
class Solution {
public:
int scheduleCourse(vector<vector<int>>& courses) {
vector<pair<int, int>> v;
for (const vector<int>& c : courses) {
v.emplace_back(c[1], c[0]);
}
sort(v.begin(), v.end());
priority_queue<int> heap;
int current = 0;
for (int i = 0; i < v.size(); i++) {
heap.push(v[i].second);
current += v[i].second;
if (current > v[i].first) {
current -= heap.top();
heap.pop();
}
}
return heap.size();
}
};