You are asked to design a task manager that supports:
add(userId, taskId, priority) - Add a new taskedit(taskId, newPriority) - Update the priority of a taskrmv(taskId) - Remove a taskexecTop() - Execute and remove the task with highest priority (if tie, highest taskId)Rules:
execTop() always executes the task with the highest priorityexecTop() should return the userId of the executed task1 <= userId, taskId, priority <= 10^5Use a combination of:
Operations:
add: Insert into both HashMap and TreeSetedit: Remove old task from TreeSet, update priority, reinsertrmv: Remove task from both structuresexecTop: Poll the first task from TreeSet (highest priority), return its userIdWhy this approach works:
Alternative approaches considered:
Example Operations:
TaskManager tm = new TaskManager([]);
tm.add(1, 101, 5); // Add task 101 with priority 5 for user 1
tm.add(2, 102, 3); // Add task 102 with priority 3 for user 2
tm.add(1, 103, 5); // Add task 103 with priority 5 for user 1
tm.execTop(); // Should return 1 (task 103 has higher taskId than 101)
tm.edit(102, 7); // Update task 102 priority to 7
tm.execTop(); // Should return 2 (task 102 now has highest priority)
Step-by-step execution:
import java.util.*;
class Task {
int userId;
int taskId;
int priority;
Task(int u, int t, int p) {
userId = u;
taskId = t;
priority = p;
}
}
class TaskManager {
private Map<Integer, Task> taskInfo = new HashMap<>();
private TreeSet<Task> taskSet;
public TaskManager(List<List<Integer>> tasks) {
taskSet = new TreeSet<>((a, b) -> {
if (a.priority != b.priority) {
return Integer.compare(b.priority, a.priority); // higher priority first
}
if (a.taskId != b.taskId) {
return Integer.compare(b.taskId, a.taskId); // higher taskId first
}
return Integer.compare(a.userId, b.userId); // tie breaker for stability
});
for (List<Integer> t : tasks) {
add(t.get(0), t.get(1), t.get(2));
}
}
public void add(int userId, int taskId, int priority) {
Task task = new Task(userId, taskId, priority);
taskInfo.put(taskId, task);
taskSet.add(task);
}
public void edit(int taskId, int newPriority) {
Task old = taskInfo.get(taskId);
if (old == null) return;
taskSet.remove(old);
Task updated = new Task(old.userId, taskId, newPriority);
taskInfo.put(taskId, updated);
taskSet.add(updated);
}
public void rmv(int taskId) {
Task old = taskInfo.get(taskId);
if (old == null) return;
taskSet.remove(old);
taskInfo.remove(taskId);
}
public int execTop() {
if (taskSet.isEmpty()) return -1;
Task top = taskSet.first(); // highest priority, highest taskId
taskSet.remove(top);
taskInfo.remove(top.taskId);
return top.userId;
}
}