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;
    }
}