-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
design-a-todo-list.cpp
114 lines (100 loc) · 3.92 KB
/
design-a-todo-list.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// Time: ctor: O(1)
// addTask: O(l + logn), n is the number of user's tasks, l is the max length of a task
// getAllTasks: O(r), r is the length of result
// getTasksForTag: O(r * c), r is the length of result, c is the length of the tag
// completeTask: O(l + logn)
// Space: O(n * l)
// bst
class TodoList {
public:
TodoList() {
}
int addTask(int userId, string taskDescription, int dueDate, vector<string> tags) {
tasks_.emplace_back(dueDate, taskDescription, unordered_set<string>(cbegin(tags), cend(tags)));
user_taskids_[to_string(userId)][dueDate] = size(tasks_);
return size(tasks_);
}
vector<string> getAllTasks(int userId) {
vector<string> result;
const auto& key = to_string(userId);
if (user_taskids_.count(key)) {
for (const auto& [_, i] : user_taskids_[key]) {
result.emplace_back(std::get<1>(tasks_[i - 1]));
}
}
return result;
}
vector<string> getTasksForTag(int userId, string tag) {
vector<string> result;
const auto& key = to_string(userId);
if (user_taskids_.count(key)) {
for (const auto& [_, i] : user_taskids_[key]) {
if (std::get<2>(tasks_[i - 1]).count(tag)) {
result.emplace_back(std::get<1>(tasks_[i - 1]));
}
}
}
return result;
}
void completeTask(int userId, int taskId) {
if (!(taskId - 1 < size(tasks_) && user_taskids_.count(to_string(userId)))) {
return;
}
user_taskids_[to_string(userId)].erase(std::get<0>(tasks_[taskId - 1]));
}
private:
vector<tuple<int, string, unordered_set<string>>> tasks_;
unordered_map<string, map<int, int>> user_taskids_;
};
// Time: ctor: O(1)
// addTask: O(l + t * logn), n is the number of user's tasks, l is the max length of a task, t is the number of tags
// getAllTasks: O(r), r is the length of result
// getTasksForTag: O(r), r is the length of result
// completeTask: O(l + t * logn)
// Space: O(n * (l + t))
// bst
class TodoList2 {
public:
TodoList2() {
}
int addTask(int userId, string taskDescription, int dueDate, vector<string> tags) {
tasks_.emplace_back(dueDate, taskDescription, unordered_set<string>(cbegin(tags), cend(tags)));
user_taskids_[to_string(userId)][dueDate] = size(tasks_);
for (const auto& tag : std::get<2>(tasks_.back())) {
user_taskids_[to_string(userId) + '-' + tag][dueDate] = size(tasks_);
}
return size(tasks_);
}
vector<string> getAllTasks(int userId) {
vector<string> result;
const auto& key = to_string(userId);
if (user_taskids_.count(key)) {
for (const auto& [_, i] : user_taskids_[key]) {
result.emplace_back(std::get<1>(tasks_[i - 1]));
}
}
return result;
}
vector<string> getTasksForTag(int userId, string tag) {
vector<string> result;
const auto& key = to_string(userId) + '-' + tag;
if (user_taskids_.count(key)) {
for (const auto& [_, i] : user_taskids_[key]) {
result.emplace_back(std::get<1>(tasks_[i - 1]));
}
}
return result;
}
void completeTask(int userId, int taskId) {
if (!(taskId - 1 < size(tasks_) && user_taskids_.count(to_string(userId)))) {
return;
}
user_taskids_[to_string(userId)].erase(std::get<0>(tasks_[taskId - 1]));
for (const auto& tag : std::get<2>(tasks_[taskId - 1])) {
user_taskids_[to_string(userId) + '-' + tag].erase(std::get<0>(tasks_[taskId - 1]));
}
}
private:
vector<tuple<int, string, unordered_set<string>>> tasks_;
unordered_map<string, map<int, int>> user_taskids_;
};