Design Task Manager
IntuitionThe main goal is to manage tasks efficiently by using appropriate data structures for quick retrieval, insertion, and removal operations. Using a prior
# Intuition
The main goal is to manage tasks efficiently by using appropriate data structures for quick retrieval, insertion, and removal operations. Using a priority queue ensures that the highest priority task is always available for execution, and auxiliary data structures help in managing task metadata.

# Approach
1. **Data Structures**:
   - `taskPriority`: A `HashMap` to store the mapping of `taskId` to its priority.
   - `taskUser`: A `HashMap` to store the mapping of `taskId` to the `userId` who created it.
   - `pq`: A `PriorityQueue` to store tasks, prioritizing by descending order of priority and `taskId`.
   - `removedTasks`: A `HashSet` to track tasks marked for removal.

2. **Initialization**:
   - The constructor takes a list of tasks, each represented as `[userId, taskId, priority]`.
   - The tasks are added to the data structures using the `add` method to ensure consistency.

3. **Operations**:
   - **`add(userId, taskId, priority)`**:
     - Adds a new task to the `taskPriority`, `taskUser`, and `pq`.
     - If the task was previously marked as removed, it is removed from the `removedTasks` set.
   - **`edit(taskId, newPriority)`**:
     - Updates the priority of an existing task in `taskPriority`.
     - The task is re-added to the `pq` with the new priority to maintain order.
   - **`rmv(taskId)`**:
     - Removes the task metadata from `taskPriority` and `taskUser`.
     - Marks the task as removed by adding it to the `removedTasks` set.
   - **`execTop()`**:
     - Retrieves the highest-priority task from the `pq`.
     - Ensures the task is valid by checking against the `removedTasks` set and the current state in `taskPriority`.
     - If valid, removes the task metadata and returns the associated `userId`.

4. **Edge Cases**:
   - If no tasks are available to execute, `execTop` returns `-1`.

# Complexity
- **Time Complexity**:
  - Adding a task (`add`): $$O(\log n)$$ due to the priority queue insertion.
  - Editing a task (`edit`): $$O(\log n)$$ for priority queue insertion.
  - Removing a task (`rmv`): $$O(1)$$ for map operations.
  - Executing the top task (`execTop`): $$O(\log n)$$ for priority queue polling and potential re-checks.

- **Space Complexity**:
  - $$O(n)$$ where $$n$$ is the number of tasks, for storing tasks in `taskPriority`, `taskUser`, and `pq`.

# Code
```cpp []
class TaskManager {
private:
    unordered_map<int, int> taskPriority; // Maps taskId to priority
    unordered_map<int, int> taskUser;     // Maps taskId to userId
    priority_queue<pair<int, int>, vector<pair<int, int>>,
                   function<bool(pair<int, int>, pair<int, int>)>>
        pq;                          // Priority queue for tasks
    unordered_set<int> removedTasks; // Set to track removed tasks

public:
    TaskManager(vector<vector<int>>& tasks)
        : pq([](pair<int, int> a, pair<int, int> b) {
              if (a.second != b.second) {
                  return a.second < b.second; // Higher priority first
              } else {
                  return a.first < b.first; // Higher taskId first
              }
          }) {
        for (const auto& task : tasks) {
            int userId = task[0];
            int taskId = task[1];
            int priority = task[2];
            add(userId, taskId, priority);
        }
    }

    void add(int userId, int taskId, int priority) {
        if (removedTasks.count(taskId)) {
            removedTasks.erase(
                taskId); // Remove from removed tasks if it was marked
        }
        taskPriority[taskId] = priority;
        taskUser[taskId] = userId;
        pq.emplace(taskId, priority);
    }

    void edit(int taskId, int newPriority) {
        if (taskPriority.count(taskId)) {
            taskPriority[taskId] = newPriority;
            pq.emplace(taskId, newPriority);
        }
    }

    void rmv(int taskId) {
        taskPriority.erase(taskId);
        taskUser.erase(taskId);
        removedTasks.insert(taskId); // Mark the task as removed
    }

    int execTop() {
        while (!pq.empty()) {
            auto [taskId, priority] = pq.top();
            pq.pop();

            // Check if the task is still valid
            if (!removedTasks.count(taskId) && taskPriority.count(taskId) &&
                taskPriority[taskId] == priority) {
                // Task is valid, remove it from the maps
                int userId = taskUser[taskId];
                taskPriority.erase(taskId);
                taskUser.erase(taskId);
                return userId;
            }
        }
        return -1; // No valid tasks to execute
    }
};
```
```JAVA []
class TaskManager {
    private Map<Integer, Integer> taskPriority; // Maps taskId to priority
    private Map<Integer, Integer> taskUser ; // Maps taskId to userId
    private PriorityQueue<int[]> pq; // Priority queue for tasks
    private Set<Integer> removedTasks; // Set to track removed tasks

    public TaskManager(List<List<Integer>> tasks) {
        taskPriority = new HashMap<>();
        taskUser  = new HashMap<>();
        pq = new PriorityQueue<>((a, b) -> {
            if (a[1] != b[1]) {
                return b[1] - a[1]; // Higher priority first
            } else {
                return b[0] - a[0]; // Higher taskId first
            }
        });
        removedTasks = new HashSet<>();

        for (List<Integer> task : tasks) {
            int userId = task.get(0);
            int taskId = task.get(1);
            int priority = task.get(2);
            add(userId, taskId, priority); // Use add method to ensure consistency
        }
    }

    public void add(int userId, int taskId, int priority) {
        if (removedTasks.contains(taskId)) {
            removedTasks.remove(taskId); // Remove from removed tasks if it was marked
        }
        taskPriority.put(taskId, priority);
        taskUser .put(taskId, userId);
        pq.offer(new int[]{taskId, priority});
    }

    public void edit(int taskId, int newPriority) {
        if (taskPriority.containsKey(taskId)) {
            taskPriority.put(taskId, newPriority);
            pq.offer(new int[]{taskId, newPriority});
        }
    }

    public void rmv(int taskId) {
        taskPriority.remove(taskId);
        taskUser .remove(taskId);
        removedTasks.add(taskId); // Mark the task as removed
    }

    public int execTop() {
        while (!pq.isEmpty()) {
            int[] topTask = pq.poll();
            int taskId = topTask[0];
            int priority = topTask[1];

            // Check if the task is still valid
            if (!removedTasks.contains(taskId) && taskPriority.containsKey(taskId) && taskPriority.get(taskId) == priority) {
                // Task is valid, remove it from the maps
                int userId = taskUser .get(taskId);
                taskPriority.remove(taskId);
                taskUser .remove(taskId);
                return userId;
            }
        }
        return -1; // No valid tasks to execute
    }
}
```
['C++', 'Java']