Optimal Priority Queue & HashMap Solution in JAVA ,C++ & PYTHON
Building a Task Manager in Java, C++, and Python: A Solution for Efficient Task ManagementIn this blog, we will walk through a task management solution that is
**Building a Task Manager in Java, C++, and Python: A Solution for Efficient Task Management**

In this blog, we will walk through a task management solution that is implemented in **Java**, **C++**, and **Python**. We aim to create a system where tasks can be added, edited, removed, and the task with the highest priority can be executed efficiently. The solution will focus on using efficient data structures, such as **priority queues**, **hash maps**, and **hash sets**, to manage tasks and their priorities.

---

### **Problem Overview**

We need to create a **Task Manager** system that can:
1. **Add** new tasks.
2. **Edit** the priority of existing tasks.
3. **Remove** tasks.
4. **Execute the highest priority task** (based on priority and task ID).

The key challenge is managing these tasks efficiently, especially when editing priorities and removing tasks dynamically.

---

### **Solution Approach**

The **TaskManager** uses the following data structures:
- **`HashMap<Integer, int[]>`**: To store task details, where the key is the `taskId` and the value is an array holding `[userId, priority]`.
- **`HashSet<String>`**: To track invalid or deleted tasks, preventing them from being executed.
- **`PriorityQueue<int[]>`**: To maintain the tasks in a way that the highest priority task can be executed first.

### **Java Implementation**

```java
import java.util.*;

class TaskManager {
    HashMap<Integer, int[]> map = new HashMap<>();
    HashSet<String> del = new HashSet<>();
    PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> {
        if (a[2] == b[2]) {
            return Integer.compare(b[1], a[1]);
        }
        return Integer.compare(b[2], a[2]);
    });

    public TaskManager(List<List<Integer>> tasks) {
        for (List<Integer> task : tasks) {
            map.put(task.get(1), new int[] { task.get(0), task.get(2) });
            pq.add(new int[] { task.get(0), task.get(1), task.get(2) });
        }
    }

    public void add(int userId, int taskId, int priority) {
        map.put(taskId, new int[] { userId, priority });
        pq.add(new int[] { userId, taskId, priority });
    }

    public void edit(int taskId, int newPriority) {
        if (map.containsKey(taskId)) {
            int[] temp = map.get(taskId);
            String invalid = taskId + ":" + temp[1];
            if (newPriority != temp[1]) {
                del.add(invalid);
                map.put(taskId, new int[] { temp[0], newPriority });
                pq.add(new int[] { temp[0], taskId, newPriority });
            }
        }
    }

    public void rmv(int taskId) {
        if (map.containsKey(taskId)) {
            String temp = taskId + ":" + map.get(taskId)[1];
            del.add(temp);
            map.remove(taskId);
        }
    }

    public int execTop() {
        while (!pq.isEmpty()) {
            int[] tp = pq.peek();
            String temp = tp[1] + ":" + tp[2];
            if (del.contains(temp)) {
                pq.poll();
                del.remove(temp);
            } else {
                pq.poll();
                map.remove(tp[1]);
                return tp[0];
            }
        }
        return -1;
    }
}
```

### **Explanation of Java Code**

- **`TaskManager(List<List<Integer>> tasks)`**: Initializes the task manager with a list of tasks. Each task is represented by a list where:
  - `task.get(0)` is the `userId`
  - `task.get(1)` is the `taskId`
  - `task.get(2)` is the `priority`
- **`add()`**: Adds a new task to the system by updating the map and adding it to the priority queue.
- **`edit()`**: Edits the priority of an existing task. If the priority is changed, the old task is marked as invalid, and the updated task is added to the system.
- **`rmv()`**: Removes a task from both the map and the queue.
- **`execTop()`**: Executes the task with the highest priority. It removes invalid tasks from the queue and returns the `userId` of the highest-priority valid task.

---

### **C++ Implementation**

The C++ implementation closely mirrors the logic in Java. The main difference lies in the syntax and the usage of C++ standard libraries.

```cpp
#include <iostream>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <queue>
#include <algorithm>

using namespace std;

class TaskManager {
public:
    unordered_map<int, vector<int>> map;
    unordered_set<string> del;
    priority_queue<vector<int>> pq;

    TaskManager(vector<vector<int>>& tasks) {
        for (auto& task : tasks) {
            map[task[1]] = {task[0], task[2]};
            pq.push({task[0], task[1], task[2]});
        }
    }

    void add(int userId, int taskId, int priority) {
        map[taskId] = {userId, priority};
        pq.push({userId, taskId, priority});
    }

    void edit(int taskId, int newPriority) {
        if (map.find(taskId) != map.end()) {
            vector<int>& temp = map[taskId];
            string invalid = to_string(taskId) + ":" + to_string(temp[1]);
            if (newPriority != temp[1]) {
                del.insert(invalid);
                map[taskId] = {temp[0], newPriority};
                pq.push({temp[0], taskId, newPriority});
            }
        }
    }

    void rmv(int taskId) {
        if (map.find(taskId) != map.end()) {
            string temp = to_string(taskId) + ":" + to_string(map[taskId][1]);
            del.insert(temp);
            map.erase(taskId);
        }
    }

    int execTop() {
        while (!pq.empty()) {
            vector<int> tp = pq.top();
            string temp = to_string(tp[1]) + ":" + to_string(tp[2]);
            if (del.find(temp) != del.end()) {
                pq.pop();
                del.erase(temp);
            } else {
                pq.pop();
                map.erase(tp[1]);
                return tp[0];
            }
        }
        return -1;
    }
};
```

### **Explanation of C++ Code**

- **`unordered_map`** is used for mapping task IDs to user IDs and priorities.
- **`unordered_set`** is used to track deleted tasks.
- **`priority_queue`** is used to prioritize tasks based on their priority and task IDs.
- The methods are similar to those in the Java implementation.

---

### **Python Implementation**

In Python, the solution is more concise due to the high-level nature of the language.

```python
import heapq

class TaskManager:
    def __init__(self, tasks):
        self.map = {}
        self.del_set = set()
        self.pq = []
        for task in tasks:
            self.map[task[1]] = [task[0], task[2]]
            heapq.heappush(self.pq, (-task[2], -task[1], task[0]))  # Max-heap based on priority and taskId

    def add(self, userId, taskId, priority):
        self.map[taskId] = [userId, priority]
        heapq.heappush(self.pq, (-priority, -taskId, userId))

    def edit(self, taskId, newPriority):
        if taskId in self.map:
            temp = self.map[taskId]
            invalid = f"{taskId}:{temp[1]}"
            if newPriority != temp[1]:
                self.del_set.add(invalid)
                self.map[taskId] = [temp[0], newPriority]
                heapq.heappush(self.pq, (-newPriority, -taskId, temp[0]))

    def rmv(self, taskId):
        if taskId in self.map:
            temp = f"{taskId}:{self.map[taskId][1]}"
            self.del_set.add(temp)
            del self.map[taskId]

    def execTop(self):
        while self.pq:
            tp = self.pq[0]
            temp = f"{-tp[1]}:{-tp[0]}"
            if temp in self.del_set:
                heapq.heappop(self.pq)
                self.del_set.remove(temp)
            else:
                heapq.heappop(self.pq)
                del self.map[-tp[1]]
                return tp[2]
        return -1
```

### **Explanation of Python Code**

- **`heapq`** is used to create a priority queue in Python. Since Python’s heapq is a min-heap, we negate values to simulate a max-heap.
- The logic remains the same as in the Java and C++ implementations, with some Python-specific differences like the use of `set` for invalid tasks.

---

### **Conclusion**

In this blog, we demonstrated how to implement a **Task Manager** system in **Java**, **C++**, and **Python**. This solution uses efficient data structures such as **priority queues**, **hash maps**, and **hash sets** to manage tasks with dynamic priorities, additions, and removals. Each implementation uses language-specific features but follows the same core logic.

By leveraging these data structures, the solution can handle
['Hash Table', 'Ordered Map', 'Heap (Priority Queue)', 'Python', 'C++', 'Java', 'Python3']