diff --git a/leetcode/3401-3500/3408.Design-Task-Manager/README.md b/leetcode/3401-3500/3408.Design-Task-Manager/README.md index 4c979a7eb..2f9f78444 100755 --- a/leetcode/3401-3500/3408.Design-Task-Manager/README.md +++ b/leetcode/3401-3500/3408.Design-Task-Manager/README.md @@ -1,28 +1,42 @@ # [3408.Design Task Manager][title] -> [!WARNING|style:flat] -> This question is temporarily unanswered if you have good ideas. Welcome to [Create Pull Request PR](https://github.com/kylesliu/awesome-golang-algorithm) - ## Description +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. -**Example 1:** +Implement the `TaskManager` class: -``` -Input: a = "11", b = "1" -Output: "100" -``` +- `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. -### 思路1 -> ... -Design Task Manager -```go -``` +- `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. +``` ## 结语 diff --git a/leetcode/3401-3500/3408.Design-Task-Manager/Solution.go b/leetcode/3401-3500/3408.Design-Task-Manager/Solution.go index d115ccf5e..1570e8d71 100644 --- a/leetcode/3401-3500/3408.Design-Task-Manager/Solution.go +++ b/leetcode/3401-3500/3408.Design-Task-Manager/Solution.go @@ -1,5 +1,119 @@ package Solution -func Solution(x bool) bool { +import ( + "container/heap" +) + +type task3408 struct { + UserID, ID, Priority int + index int +} + +type TaskList struct { + items []*task3408 +} + +func (t *TaskList) Len() int { + return len(t.items) +} +func (t *TaskList) Swap(i, j int) { + t.items[i], t.items[j] = t.items[j], t.items[i] + t.items[i].index = i + t.items[j].index = j +} + +func (t *TaskList) Less(i, j int) bool { + a, b := t.items[i], t.items[j] + if a.Priority == b.Priority { + return a.ID > b.ID + } + return a.Priority > b.Priority +} + +func (t *TaskList) Push(x any) { + item := x.(*task3408) + item.index = len(t.items) + t.items = append(t.items, item) +} + +func (t *TaskList) Pop() any { + old := t.items + l := len(old) + x := old[l-1] + t.items = old[:l-1] return x } + +type TaskManager struct { + taskHeap *TaskList + taskIndex map[int]*task3408 +} + +func Constructor(tasks [][]int) TaskManager { + th := &TaskList{items: make([]*task3408, 0)} + tm := TaskManager{taskHeap: th, taskIndex: make(map[int]*task3408)} + // userId, taskId, priority + for _, task := range tasks { + tm.Add(task[0], task[1], task[2]) + } + return tm +} + +func (this *TaskManager) Add(userId int, taskId int, priority int) { + item := &task3408{ + UserID: userId, + ID: taskId, + Priority: priority, + } + this.taskIndex[taskId] = item + heap.Push(this.taskHeap, item) + //this.taskHeap.Push(item) +} + +func (this *TaskManager) Edit(taskId int, newPriority int) { + item := this.taskIndex[taskId] + item.Priority = newPriority + heap.Fix(this.taskHeap, item.index) +} + +func (this *TaskManager) Rmv(taskId int) { + item := this.taskIndex[taskId] + delete(this.taskIndex, taskId) + heap.Remove(this.taskHeap, item.index) +} + +func (this *TaskManager) ExecTop() int { + if len(this.taskHeap.items) == 0 { + return -1 + } + top := heap.Pop(this.taskHeap).(*task3408) + return top.UserID +} + +type op struct { + name string + userId, taskId, priority int +} + +func Solution(input [][]int, ops []op) []int { + c := Constructor(input) + var ret []int + for _, o := range ops { + if o.name == "add" { + c.Add(o.userId, o.taskId, o.priority) + continue + } + if o.name == "edit" { + c.Edit(o.taskId, o.priority) + continue + } + if o.name == "exec" { + ret = append(ret, c.ExecTop()) + continue + } + if o.name == "rmv" { + c.Rmv(o.taskId) + } + } + return ret +} diff --git a/leetcode/3401-3500/3408.Design-Task-Manager/Solution_test.go b/leetcode/3401-3500/3408.Design-Task-Manager/Solution_test.go index 14ff50eb4..66e9b8c49 100644 --- a/leetcode/3401-3500/3408.Design-Task-Manager/Solution_test.go +++ b/leetcode/3401-3500/3408.Design-Task-Manager/Solution_test.go @@ -10,30 +10,38 @@ func TestSolution(t *testing.T) { // 测试用例 cases := []struct { name string - inputs bool - expect bool + inputs [][]int + ops []op + expect []int }{ - {"TestCase", true, true}, - {"TestCase", true, true}, - {"TestCase", false, false}, + {"TestCase1", [][]int{ + {1, 101, 10}, {2, 102, 20}, {3, 103, 15}, + }, []op{ + {name: "add", userId: 4, taskId: 104, priority: 5}, + {name: "edit", taskId: 102, priority: 8}, + {name: "exec"}, + {name: "rmv", taskId: 101}, + {name: "add", userId: 5, taskId: 105, priority: 15}, + {name: "exec"}, + }, []int{3, 5}}, } // 开始测试 for i, c := range cases { t.Run(c.name+" "+strconv.Itoa(i), func(t *testing.T) { - got := Solution(c.inputs) + got := Solution(c.inputs, c.ops) if !reflect.DeepEqual(got, c.expect) { - t.Fatalf("expected: %v, but got: %v, with inputs: %v", - c.expect, got, c.inputs) + t.Fatalf("expected: %v, but got: %v, with inputs: %v %v", + c.expect, got, c.inputs, c.ops) } }) } } -// 压力测试 +// 压力测试 func BenchmarkSolution(b *testing.B) { } -// 使用案列 +// 使用案列 func ExampleSolution() { }