Skip to main content

Command Palette

Search for a command to run...

Solving Leetcode Interviews in Seconds with AI: Design Task Manager

Updated
4 min read

Introduction

In this blog post, we will explore how to solve the LeetCode problem "3408" using AI. LeetCode is a popular platform for preparing for coding interviews, and with the help of AI tools like Chatmagic, we can generate solutions quickly and efficiently - helping you pass the interviews and get the job offer without having to study for months.

Problem Statement

There is a task management system that allows users to manage their tasks, each associated with a priority. The system should efficiently handle adding, modifying, executing, and removing tasks. Implement the TaskManager class: TaskManager(vector>& tasks) initializes the task manager with a list of user-task-priority triples. Each element in the input list is of the form [userId, taskId, priority], which adds a task to the specified user with the given priority. void add(int userId, int taskId, int priority) adds a task with the specified taskId and priority to the user with userId. It is guaranteed that taskId does not exist in the system. void edit(int taskId, int newPriority) updates the priority of the existing taskId to newPriority. It is guaranteed that taskId exists in the system. void rmv(int taskId) removes the task identified by taskId from the system. It is guaranteed that taskId exists in the system. int execTop() executes the task with the highest priority across all users. If there are multiple tasks with the same highest priority, execute the one with the highest taskId. After executing, the taskId is removed from the system. Return the userId associated with the executed task. If no tasks are available, return -1. Note that a user may be assigned multiple tasks. Example 1: Input: ["TaskManager", "add", "edit", "execTop", "rmv", "add", "execTop"] [[[[1, 101, 10], [2, 102, 20], [3, 103, 15]]], [4, 104, 5], [102, 8], [], [101], [5, 105, 15], []] Output: [null, null, null, 3, null, null, 5] Explanation TaskManager taskManager = new TaskManager([[1, 101, 10], [2, 102, 20], [3, 103, 15]]); // Initializes with three tasks for Users 1, 2, and 3. taskManager.add(4, 104, 5); // Adds task 104 with priority 5 for User 4. taskManager.edit(102, 8); // Updates priority of task 102 to 8. taskManager.execTop(); // return 3. Executes task 103 for User 3. taskManager.rmv(101); // Removes task 101 from the system. taskManager.add(5, 105, 15); // Adds task 105 with priority 15 for User 5. taskManager.execTop(); // return 5. Executes task 105 for User 5. Constraints: 1 <= tasks.length <= 105 0 <= userId <= 105 0 <= taskId <= 105 0 <= priority <= 109 0 <= newPriority <= 109 At most 2 * 105 calls will be made in total to add, edit, rmv, and execTop methods. The input is generated such that taskId will be valid.

Explanation

Here's a breakdown of the optimal approach, complexity analysis, and the Python code for the TaskManager:

  • High-Level Approach:

    • Use a hash map (task_map) to store task information (user ID and priority) indexed by taskId for fast access during edit and rmv operations.
    • Employ a priority queue (priority_queue) to efficiently retrieve the task with the highest priority. Store tasks in the priority queue as tuples: (-priority, -taskId, userId) to enable retrieving the maximum priority and, in case of ties, the maximum taskId.
    • Maintain consistency between the hash map and the priority queue by updating both data structures during add, edit, and rmv operations.
  • Complexity:

    • Runtime Complexity: O(log N) for add, edit, rmv, and execTop, where N is the number of tasks. O(N) for initialization.
    • Storage Complexity: O(N), where N is the number of tasks.

Code

    import heapq

class TaskManager:
    def __init__(self, tasks):
        self.task_map = {}  # taskId: (userId, priority)
        self.priority_queue = []  # (priority, taskId, userId)

        for user_id, task_id, priority in tasks:
            self.task_map[task_id] = (user_id, priority)
            heapq.heappush(self.priority_queue, (-priority, -task_id, user_id))

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

    def edit(self, taskId, newPriority):
        user_id, _ = self.task_map[taskId]
        self.task_map[taskId] = (user_id, newPriority)

        # Rebuild the priority queue (efficient for edit)
        self.priority_queue = []
        for task_id, (user_id, priority) in self.task_map.items():
            heapq.heappush(self.priority_queue, (-priority, -task_id, user_id))


    def rmv(self, taskId):
        del self.task_map[taskId]

        # Rebuild the priority queue after removal
        self.priority_queue = []
        for task_id, (user_id, priority) in self.task_map.items():
            heapq.heappush(self.priority_queue, (-priority, -task_id, user_id))


    def execTop(self):
        if not self.priority_queue:
            return -1

        priority, task_id, user_id = heapq.heappop(self.priority_queue)
        task_id = -task_id
        del self.task_map[task_id]

        #remove the task_id from priority queue as well
        temp_pq = []
        while self.priority_queue:
            curr_priority, curr_task_id, curr_user_id = heapq.heappop(self.priority_queue)
            if -curr_task_id != task_id:
                heapq.heappush(temp_pq, (curr_priority, curr_task_id, curr_user_id))

        self.priority_queue = temp_pq

        return user_id

More from this blog

C

Chatmagic blog

2894 posts

Solving Leetcode Interviews in Seconds with AI: Design Task Manager