3408: Design-Task-Manager
Medium
table of contents
This question took similar ideas from yesterday’s question.
Simply put, it follows a similar format where whenever we edit
a taskId’s priority, we can simply
invalidate the original priority and
append the new one onto the priority_queue.
We can do this by keeping 2 unordered_map
(taskPriority and taskUser). Since we only
need to check for valid tasks when we are executing the
task with the highest priority (from
taskPriority), we can do this by seeing if the
priority value from taskPriority matches the
one from the top value of priorityTasks:
unordered_map<int, int> taskPriority; // taskId -> priority
unordered_map<int, int> taskUser; // taskId -> userId
priority_queue<pair<int, int>> priorityTasks; // priority_queue({priority, taskId})To start off, whenever we add a new task, we simply:
void add(int userId, int taskId, int priority) {
priorityTasks.emplace(priority, taskId); // add the task to priority_queue
taskPriority[taskId] = priority; // add taskId -> priority mapping
taskUser[taskId] = userId; // add taskId -> userId mapping
}Then, when we initialise a new TaskManager, we can
simply iterate through every element and run the add
operation:
TaskManager(vector<vector<int>>& tasks) {
for (vector<int>& task : tasks) {
add(task[0], task[1], task[2]);
}
}Now, if we want to edit a taskId’s priority, we can
simply append the newPriority onto
priorityTasks and update its priority:
void edit(int taskId, int newPriority) {
priorityTasks.emplace(newPriority, taskId);
taskPriority[taskId] = newPriority;
}Similarly, if we want to remove a taskId, we just set
its taskPriority to -1 so any attempts at
validating the request fails (as it will never match any previous
priority value that has been set):
void rmv(int taskId) {
taskPriority[taskId] = -1;
}Finally, if we want to execute the task with the highest
priority, we can just iterate through and pop all
the highest priority tasks until we find one that is
valid:
int execTop() {
while (!priorityTasks.empty()) {
pair<int, int> front = priorityTasks.top(); // front.first == priority, front.second == taskId
priorityTasks.pop();
if (taskPriority[front.second] == front.first) {
taskPriority[front.second] = -1;
return taskUser[front.second];
}
}
return -1;
}code
class TaskManager {
public:
TaskManager(vector<vector<int>>& tasks) {
for (vector<int>& task : tasks) {
add(task[0], task[1], task[2]);
}
}
void add(int userId, int taskId, int priority) {
priorityTasks.emplace(priority, taskId);
taskPriority[taskId] = priority;
taskUser[taskId] = userId;
}
void edit(int taskId, int newPriority) {
priorityTasks.emplace(newPriority, taskId);
taskPriority[taskId] = newPriority;
}
void rmv(int taskId) {
taskPriority[taskId] = -1;
}
int execTop() {
while (!priorityTasks.empty()) {
pair<int, int> front = priorityTasks.top();
priorityTasks.pop();
if (taskPriority[front.second] == front.first) {
taskPriority[front.second] = -1;
return taskUser[front.second];
}
}
return -1;
}
private:
unordered_map<int, int> taskPriority;
unordered_map<int, int> taskUser;
priority_queue<pair<int, int>> priorityTasks;
};
/**
* Your TaskManager object will be instantiated and called as such:
* TaskManager* obj = new TaskManager(tasks);
* obj->add(userId,taskId,priority);
* obj->edit(taskId,newPriority);
* obj->rmv(taskId);
* int param_4 = obj->execTop();
*/