✅Easy using Map and Priority || 100% beats🔥
IntuitionWe need a task management system where we can:
Add tasks with a priority to users.
Edit the priority of existing tasks.
Remove tasks.
Execute the highe
# Intuition
We need a task management system where we can:
1. Add tasks with a priority to users.
2. Edit the priority of existing tasks.
3. Remove tasks.
4. Execute the highest-priority task (with ties broken by the taskId).

A straightforward approach is to use a PriorityQueue or a TreeMap for efficient access to the highest-priority task. However, both of these solutions have trade-offs when it comes to removing tasks or editing priorities. Therefore, a combination of TreeMap for priority-based sorting and **HashMap** for quick lookup can solve the problem efficiently.

# Approach
1. Task Representation:->
* We'll define a Task class that stores userId, taskId, and priority. This class will implement the Comparable interface so that tasks can be sorted by priority (descending order) and by taskId (descending order) in case of ties.

2. Data Structures:->
* A TreeMap will be used to maintain tasks sorted by priority and taskId. This allows us to access the highest-priority task in O(logN) time.
* A HashMap will be used to quickly access a task by its taskId in constant time O(1).

3. Operations:
* add: Add a new task to both the TreeMap (for sorting) and HashMap (for quick lookup).
* edit: Change the priority of a task, requiring removal and re-insertion in the TreeMap.
* rmv: Remove a task from both the TreeMap and HashMap.
* execTop: Retrieve and remove the highest-priority task from the **TreeMap.

4. Edge Case Handling:
* Ensure that if there are no tasks, we return -1 when calling execTop.

# Complexity
# Time complexity:
* Initialization (constructor):O(MlogM), where M is the number of tasks. Each insertion into the TreeMap takes O(logN) time, and there are M tasks to process.
* add: O(logN), where N is the number of tasks in the TreeMap because insertion requires balancing the tree.
* edit:O(logN), because removing a task and inserting it again in the TreeMap takes O(logN).
* rmv: O(logN), because removal from the TreeMap takes O(logN).
execTop: O(logN), because retrieving and removing the top element from the TreeMap takes O(logN).

# Space complexity:
O(N), where N is the number of tasks, because we are storing tasks in both the TreeMap and HashMap.

# Code
````java []
import java.util.*;

class TaskManager {
    private static class Task implements Comparable<Task> {
        int userId, taskId, priority;

        Task(int userId, int taskId, int priority) {
            this.userId = userId;
            this.taskId = taskId;
            this.priority = priority;
        }

        @Override
        public int compareTo(Task other) {
            if (this.priority != other.priority) {
                return Integer.compare(other.priority, this.priority);
            }
            return Integer.compare(other.taskId, this.taskId);
        }
    }

    private final TreeMap<Task, Integer> sortedTasks;
    private final Map<Integer, Task> taskMap; 

    public TaskManager(List<List<Integer>> tasks) {
        sortedTasks = new TreeMap<>();
        taskMap = new HashMap<>();

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

    public void add(int userId, int taskId, int priority) {
        Task task = new Task(userId, taskId, priority);
        sortedTasks.put(task, userId);
        taskMap.put(taskId, task);
    }

    public void edit(int taskId, int newPriority) {
        Task task = taskMap.get(taskId);
        if (task != null) {
            sortedTasks.remove(task);
            task.priority = newPriority;
            sortedTasks.put(task, task.userId);
        }
    }

    public void rmv(int taskId) {
        Task task = taskMap.get(taskId);
        if (task != null) {
            sortedTasks.remove(task);
            taskMap.remove(taskId);
        }
    }

    public int execTop() {
        if (sortedTasks.isEmpty()) {
            return -1;
        }
        Task topTask = sortedTasks.firstKey();
        sortedTasks.remove(topTask);
        taskMap.remove(topTask.taskId);
        return topTask.userId;
    }
}
````
````cpp []
#include <iostream>
#include <vector>
#include <map>
#include <unordered_map>

using namespace std;

class TaskManager {
private:
    struct Task {
        int userId, taskId, priority;

        // Default constructor
        Task() : userId(0), taskId(0), priority(0) {}

        // Parameterized constructor
        Task(int userId, int taskId, int priority)
            : userId(userId), taskId(taskId), priority(priority) {}

        // Define the comparison operator to maintain the correct order in the sorted container
        bool operator<(const Task& other) const {
            if (priority != other.priority) {
                return priority > other.priority; // Higher priority comes first
            }
            return taskId > other.taskId; // If priority is the same, higher taskId comes first
        }

        // Define the copy constructor
        Task(const Task& other) = default;
        // Define the move constructor
        Task(Task&& other) noexcept = default;

        // Define the copy assignment operator
        Task& operator=(const Task& other) = default;

        // Define the move assignment operator
        Task& operator=(Task&& other) noexcept = default;
    };

    map<Task, int> sortedTasks;
    unordered_map<int, Task> taskMap;

public:
    TaskManager(vector<vector<int>>& tasks) {
        for (auto& task : tasks) {
            int userId = task[0], taskId = task[1], priority = task[2];
            add(userId, taskId, priority);
        }
    }

    void add(int userId, int taskId, int priority) {
        Task task(userId, taskId, priority);
        sortedTasks[task] = userId;
        taskMap[taskId] = task;
    }

    void edit(int taskId, int newPriority) {
        auto taskIt = taskMap.find(taskId);
        if (taskIt != taskMap.end()) {
            Task task = taskIt->second;
            sortedTasks.erase(task);
            task.priority = newPriority;
            sortedTasks[task] = task.userId;
            taskMap[taskId] = task;
        }
    }

    void rmv(int taskId) {
        auto taskIt = taskMap.find(taskId);
        if (taskIt != taskMap.end()) {
            Task task = taskIt->second;
            sortedTasks.erase(task);
            taskMap.erase(taskId);
        }
    }

    int execTop() {
        if (sortedTasks.empty()) {
            return -1;
        }
        auto topTask = sortedTasks.begin();
        Task top = topTask->first;
        sortedTasks.erase(topTask);
        taskMap.erase(top.taskId);
        return top.userId;
    }
};
````
![upvote.png](https://assets.leetcode.com/users/images/4778d79e-5aca-4b80-8827-6c674ef3a1d7_1736002418.8532643.png)
['Heap (Priority Queue)', 'C++', 'Java']