Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 30 additions & 16 deletions leetcode/3401-3500/3408.Design-Task-Manager/README.md
Original file line number Diff line number Diff line change
@@ -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<vector<int>>& 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.
```

## 结语

Expand Down
116 changes: 115 additions & 1 deletion leetcode/3401-3500/3408.Design-Task-Manager/Solution.go
Original file line number Diff line number Diff line change
@@ -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
}
28 changes: 18 additions & 10 deletions leetcode/3401-3500/3408.Design-Task-Manager/Solution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
}
Loading