C++ | Design Question | Set & Map Implementation | Beats 100%
IntuitionThe question is to design a Task Manager class.
Upon careful observation we can see that we can use the taskId as the key to store userId and priority
# Intuition
<!-- Describe your first thoughts on how to solve this problem. -->
The question is to design a Task Manager class.
Upon careful observation we can see that we can use the `taskId` as the key to store `userId` and `priority` of various tasks. And for `execTop()` function we need to retrive the task with highest `priority` and highest `taskId`, so we use `set` as it is easy to fetch and delete elements.

# Approach
<!-- Describe your approach to solving the problem. -->
- Implement the function `TaskManager` and add user,taskId,priority in the respective maps and set.

- Then for `add` function, simply add the data given.

- In `edit`, we need to edit the `priority` of the given `taskId`
so we need to edit them in both from the hash-map `task_priority` and set `priority_taskId`. Had we used a priority_queue instead of a set, it would have been difficult to update the priorty. Hence we first fetch the old_priority from the hash-map `task_priority` and erase it from the set and then insert the given task with its new priority.

- In `rmv`, we need to remove the task, we need to update both the hashmap and the set.

- In `execTop()` function, if there are no more task left, we return -1. Else, we take the last element from the set as it stores elements in increasing order, so the highest priority with largest taskId will be present at the end. After fetching it, we remove it from the set and return the userId associated with that particular task.




# Complexity
- Time complexity: O(1)
<!-- Add your time complexity here, e.g. $$O(n)$$ -->

- Space complexity: O(n)
<!-- Add your space complexity here, e.g. $$O(n)$$ -->
![image.png](https://assets.leetcode.com/users/images/d4f1bcad-6c29-40fb-9f29-148f261bf13e_1736172985.9203663.png)


# Code
```cpp []
class TaskManager {
public:
    unordered_map<int,int>task_user;
    unordered_map<int,int>task_priority;
    set<pair<int,int>>priority_taskId;

    TaskManager(vector<vector<int>>& tasks) {

        for(auto x: tasks){
            int user = x[0], task = x[1], priority = x[2];
            task_user[task]= user;
            task_priority[task] =  priority;
            priority_taskId.insert({priority, task}); 
        }
    }
    
    void add(int userId, int taskId, int priority) {
        task_user[taskId]= userId;
        task_priority[taskId] =  priority;
        priority_taskId.insert({priority, taskId}); 
    }
    
    void edit(int taskId, int newPriority) {
        // update in the set
        int old_pr = task_priority[taskId];
        priority_taskId.erase({old_pr, taskId});

        task_priority[taskId] = newPriority;
        priority_taskId.insert({newPriority, taskId});
    }
    
    void rmv(int taskId) {
        task_user.erase(taskId);
        int pri = task_priority[taskId];
        task_priority.erase(taskId);
        priority_taskId.erase({pri, taskId});
    }
    
    int execTop() {
        if(priority_taskId.empty()) return -1;

        pair<int,int> temp = *priority_taskId.rbegin();
        priority_taskId.erase(temp);
        return task_user[temp.second];
    }
};

/**
 * 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();
 */
```
['Hash Table', 'Design', 'Ordered Set', 'C++']