Skip to content

Commit 462fec1

Browse files
committed
feat: update lc problems
1 parent 62863f5 commit 462fec1

File tree

18 files changed

+597
-47
lines changed

18 files changed

+597
-47
lines changed

solution/0000-0099/0010.Regular Expression Matching/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646

4747
<ul>
4848
<li><code>1 &lt;= s.length&nbsp;&lt;= 20</code></li>
49-
<li><code>1 &lt;= p.length&nbsp;&lt;= 30</code></li>
49+
<li><code>1 &lt;= p.length&nbsp;&lt;= 20</code></li>
5050
<li><code>s</code>&nbsp;只包含从&nbsp;<code>a-z</code>&nbsp;的小写字母。</li>
5151
<li><code>p</code>&nbsp;只包含从&nbsp;<code>a-z</code>&nbsp;的小写字母,以及字符&nbsp;<code>.</code>&nbsp;和&nbsp;<code>*</code>。</li>
5252
<li>保证每次出现字符&nbsp;<code>*</code> 时,前面都匹配到有效的字符</li>

solution/0100-0199/0100.Same Tree/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,7 @@ class Solution {
600600
}
601601
return $this->isSameTree($p->left, $q->left) && $this->isSameTree($p->right, $q->right);
602602
}
603-
}
603+
}
604604
```
605605

606606
### **...**

solution/0100-0199/0154.Find Minimum in Rotated Sorted Array II/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848

4949
<p>&nbsp;</p>
5050

51-
<p><strong>进阶:</strong>这道题与 <a href="https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array/description/">寻找旋转排序数组中的最小值</a> 类似,但 <code>nums</code> 可能包含重复元素。允许重复会影响算法的时间复杂度吗?会如何影响,为什么?</p>
51+
<p><strong>进阶:</strong>这道题与 <a href="https://leetcode.cn/problems/find-minimum-in-rotated-sorted-array/description/">寻找旋转排序数组中的最小值</a> 类似,但 <code>nums</code> 可能包含重复元素。允许重复会影响算法的时间复杂度吗?会如何影响,为什么?</p>
5252

5353
## 解法
5454

solution/0700-0799/0707.Design Linked List/README.md

+28-16
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,42 @@
66

77
<!-- 这里写题目描述 -->
88

9-
<p>设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性:<code>val</code>&nbsp;&nbsp;<code>next</code>。<code>val</code>&nbsp;是当前节点的值,<code>next</code>&nbsp;是指向下一个节点的指针/引用。如果要使用双向链表,则还需要一个属性&nbsp;<code>prev</code>&nbsp;以指示链表中的上一个节点。假设链表中的所有节点都是 0-index 的。</p>
9+
<p>你可以选择使用单链表或者双链表,设计并实现自己的链表。</p>
1010

11-
<p>在链表类中实现这些功能:</p>
11+
<p>单链表中的节点应该具备两个属性:<code>val</code> 和 <code>next</code> 。<code>val</code> 是当前节点的值,<code>next</code> 是指向下一个节点的指针/引用。</p>
12+
13+
<p>如果是双向链表,则还需要属性&nbsp;<code>prev</code>&nbsp;以指示链表中的上一个节点。假设链表中的所有节点下标从 <strong>0</strong> 开始。</p>
14+
15+
<p>实现 <code>MyLinkedList</code> 类:</p>
1216

1317
<ul>
14-
<li>get(index):获取链表中第&nbsp;<code>index</code>&nbsp;个节点的值。如果索引无效,则返回<code>-1</code>。</li>
15-
<li>addAtHead(val):在链表的第一个元素之前添加一个值为&nbsp;<code>val</code>&nbsp;的节点。插入后,新节点将成为链表的第一个节点。</li>
16-
<li>addAtTail(val):将值为&nbsp;<code>val</code> 的节点追加到链表的最后一个元素。</li>
17-
<li>addAtIndex(index,val):在链表中的第&nbsp;<code>index</code>&nbsp;个节点之前添加值为&nbsp;<code>val</code>&nbsp; 的节点。如果&nbsp;<code>index</code>&nbsp;等于链表的长度,则该节点将附加到链表的末尾。如果 <code>index</code> 大于链表长度,则不会插入节点。如果<code>index</code>小于0,则在头部插入节点。</li>
18-
<li>deleteAtIndex(index):如果索引&nbsp;<code>index</code> 有效,则删除链表中的第&nbsp;<code>index</code> 个节点。</li>
18+
<li><code>MyLinkedList()</code> 初始化 <code>MyLinkedList</code> 对象。</li>
19+
<li><code>int get(int index)</code> 获取链表中下标为 <code>index</code> 的节点的值。如果下标无效,则返回 <code>-1</code> 。</li>
20+
<li><code>void addAtHead(int val)</code> 将一个值为 <code>val</code> 的节点插入到链表中第一个元素之前。在插入完成后,新节点会成为链表的第一个节点。</li>
21+
<li><code>void addAtTail(int val)</code> 将一个值为 <code>val</code> 的节点追加到链表中作为链表的最后一个元素。</li>
22+
<li><code>void addAtIndex(int index, int val)</code> 将一个值为 <code>val</code> 的节点插入到链表中下标为 <code>index</code> 的节点之前。如果 <code>index</code> 等于链表的长度,那么该节点会被追加到链表的末尾。如果 <code>index</code> 比长度更大,该节点将 <strong>不会插入</strong> 到链表中。</li>
23+
<li><code>void deleteAtIndex(int index)</code> 如果下标有效,则删除链表中下标为 <code>index</code> 的节点。</li>
1924
</ul>
2025

2126
<p>&nbsp;</p>
2227

23-
<p><strong>示例:</strong></p>
28+
<p><strong class="example">示例:</strong></p>
2429

2530
<pre>
26-
MyLinkedList linkedList = new MyLinkedList();
27-
linkedList.addAtHead(1);
28-
linkedList.addAtTail(3);
29-
linkedList.addAtIndex(1,2); //链表变为1-&gt; 2-&gt; 3
30-
linkedList.get(1); //返回2
31-
linkedList.deleteAtIndex(1); //现在链表是1-&gt; 3
32-
linkedList.get(1); //返回3
31+
<strong>输入</strong>
32+
["MyLinkedList", "addAtHead", "addAtTail", "addAtIndex", "get", "deleteAtIndex", "get"]
33+
[[], [1], [3], [1, 2], [1], [1], [1]]
34+
<strong>输出</strong>
35+
[null, null, null, null, 2, null, 3]
36+
37+
<strong>解释</strong>
38+
MyLinkedList myLinkedList = new MyLinkedList();
39+
myLinkedList.addAtHead(1);
40+
myLinkedList.addAtTail(3);
41+
myLinkedList.addAtIndex(1, 2); // 链表变为 1-&gt;2-&gt;3
42+
myLinkedList.get(1); // 返回 2
43+
myLinkedList.deleteAtIndex(1); // 现在,链表变为 1-&gt;3
44+
myLinkedList.get(1); // 返回 3
3345
</pre>
3446

3547
<p>&nbsp;</p>
@@ -39,7 +51,7 @@ linkedList.get(1); //返回3
3951
<ul>
4052
<li><code>0 &lt;= index, val &lt;= 1000</code></li>
4153
<li>请不要使用内置的 LinkedList 库。</li>
42-
<li><code>get</code>,&nbsp;<code>addAtHead</code>,&nbsp;<code>addAtTail</code>,&nbsp;<code>addAtIndex</code>&nbsp;和&nbsp;<code>deleteAtIndex</code>&nbsp;的操作次数不超过&nbsp;<code>2000</code>。</li>
54+
<li>调用 <code>get</code><code>addAtHead</code><code>addAtTail</code><code>addAtIndex</code><code>deleteAtIndex</code> 的次数不超过 <code>2000</code> 。</li>
4355
</ul>
4456

4557
## 解法

solution/0800-0899/0850.Rectangle Area II/README_EN.md

+2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ From (1,0) to (2,3), all three rectangles overlap.
3636
<li><code>1 &lt;= rectangles.length &lt;= 200</code></li>
3737
<li><code>rectanges[i].length == 4</code></li>
3838
<li><code>0 &lt;= x<sub>i1</sub>, y<sub>i1</sub>, x<sub>i2</sub>, y<sub>i2</sub> &lt;= 10<sup>9</sup></code></li>
39+
<li><code>x<sub>i1 &lt;= </sub>x<sub>i2</sub></code></li>
40+
<li><code>y<sub>i1 &lt;=</sub> y<sub>i2</sub></code></li>
3941
</ul>
4042

4143
## Solutions

solution/0900-0999/0966.Vowel Spellchecker/README_EN.md

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
<ul>
1212
<li>Capitalization: If the query matches a word in the wordlist (<strong>case-insensitive</strong>), then the query word is returned with the same case as the case in the wordlist.
13+
1314
<ul>
1415
<li>Example: <code>wordlist = [&quot;yellow&quot;]</code>, <code>query = &quot;YellOw&quot;</code>: <code>correct = &quot;yellow&quot;</code></li>
1516
<li>Example: <code>wordlist = [&quot;Yellow&quot;]</code>, <code>query = &quot;yellow&quot;</code>: <code>correct = &quot;Yellow&quot;</code></li>
@@ -23,6 +24,7 @@
2324
<li>Example: <code>wordlist = [&quot;YellOw&quot;]</code>, <code>query = &quot;yllw&quot;</code>: <code>correct = &quot;&quot;</code> (no match)</li>
2425
</ul>
2526
</li>
27+
2628
</ul>
2729

2830
<p>In addition, the spell checker operates under the following precedence rules:</p>

solution/1500-1599/1516.Move Sub-Tree of N-Ary Tree/README_EN.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
## Description
66

7-
<p>Given the <code>root</code> of an <span data-keyword="keyword-slug">n-ary-tree</span> of unique values, and two nodes of the tree <code>p</code> and <code>q</code>.</p>
7+
<p>Given the <code>root</code> of an <span data-keyword="n-ary-tree">N-ary tree</span> of unique values, and two nodes of the tree <code>p</code> and <code>q</code>.</p>
88

99
<p>You should move the subtree of the node <code>p</code> to become a direct child of node <code>q</code>. If <code>p</code> is already a direct child of <code>q</code>, do not change anything. Node <code>p</code> <strong>must be</strong> the last child in the children list of node <code>q</code>.</p>
1010

solution/1800-1899/1894.Find the Student that Will Replace the Chalk/README_EN.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
<p>You are given a <strong>0-indexed</strong> integer array <code>chalk</code> and an integer <code>k</code>. There are initially <code>k</code> pieces of chalk. When the student number <code>i</code> is given a problem to solve, they will use <code>chalk[i]</code> pieces of chalk to solve that problem. However, if the current number of chalk pieces is <strong>strictly less</strong> than <code>chalk[i]</code>, then the student number <code>i</code> will be asked to <strong>replace</strong> the chalk.</p>
1010

11-
<p>Return <em>the <strong>index</strong> of the student that will <strong>replace</strong> the chalk</em>.</p>
11+
<p>Return <em>the <strong>index</strong> of the student that will <strong>replace</strong> the chalk pieces</em>.</p>
1212

1313
<p>&nbsp;</p>
1414
<p><strong class="example">Example 1:</strong></p>

solution/2300-2399/2302.Count Subarrays With Score Less Than K/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<!-- 这里写题目描述 -->
88

9-
<p>一个数字的 <strong>分数</strong>&nbsp;定义为数组之和 <strong>乘以</strong>&nbsp;数组的长度。</p>
9+
<p>一个数组的 <strong>分数</strong>&nbsp;定义为数组之和 <strong>乘以</strong>&nbsp;数组的长度。</p>
1010

1111
<ul>
1212
<li>比方说,<code>[1, 2, 3, 4, 5]</code>&nbsp;的分数为&nbsp;<code>(1 + 2 + 3 + 4 + 5) * 5 = 75</code>&nbsp;。</li>

solution/2300-2399/2389.Longest Subsequence With Limited Sum/README_EN.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ class Solution {
8585
}
8686
return ans;
8787
}
88-
88+
8989
private int search(int[] nums, int x) {
9090
int l = 0, r = nums.length;
9191
while (l < r) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
# [2890. Design a Todo List](https://leetcode.cn/problems/design-a-todo-list)
2+
3+
[English Version](/solution/2800-2899/2890.Design%20a%20Todo%20List/README_EN.md)
4+
5+
## 题目描述
6+
7+
<!-- 这里写题目描述 -->
8+
9+
<p>Design a Todo List Where users can add <strong>tasks</strong>, mark them as <strong>complete</strong>, or get a list of pending tasks. Users can also add <strong>tags</strong> to tasks and can filter the tasks by certain tags.</p>
10+
11+
<p>Implement the <code>TodoList</code> class:</p>
12+
13+
<ul>
14+
<li><code>TodoList()</code> Initializes the object.</li>
15+
<li><code>int addTask(int userId, String taskDescription, int dueDate, List&lt;String&gt; tags)</code> Adds a task for the user with the ID <code>userId</code> with a due date equal to <code>dueDate</code> and a list of tags attached to the task. The return value is the ID of the task. This ID starts at <code>1</code> and is <strong>sequentially</strong> increasing. That is, the first task&#39;s id should be <code>1</code>, the second task&#39;s id should be <code>2</code>, and so on.</li>
16+
<li><code>List&lt;String&gt; getAllTasks(int userId)</code> Returns a list of all the tasks not marked as complete for the user with ID <code>userId</code>, ordered by the due date. You should return an empty list if the user has no uncompleted tasks.</li>
17+
<li><code>List&lt;String&gt; getTasksForTag(int userId, String tag)</code> Returns a list of all the tasks that are not marked as complete for the user with the ID <code>userId</code> and have <code>tag</code> as one of their tags, ordered by their due date. Return an empty list if no such task exists.</li>
18+
<li><code>void completeTask(int userId, int taskId)</code> Marks the task with the ID <code>taskId</code> as completed only if the task exists and the user with the ID <code>userId</code> has this task, and it is uncompleted.</li>
19+
</ul>
20+
21+
<p>&nbsp;</p>
22+
<p><strong class="example">Example 1:</strong></p>
23+
24+
<pre>
25+
<strong>Input</strong>
26+
[&quot;TodoList&quot;, &quot;addTask&quot;, &quot;addTask&quot;, &quot;getAllTasks&quot;, &quot;getAllTasks&quot;, &quot;addTask&quot;, &quot;getTasksForTag&quot;, &quot;completeTask&quot;, &quot;completeTask&quot;, &quot;getTasksForTag&quot;, &quot;getAllTasks&quot;]
27+
[[], [1, &quot;Task1&quot;, 50, []], [1, &quot;Task2&quot;, 100, [&quot;P1&quot;]], [1], [5], [1, &quot;Task3&quot;, 30, [&quot;P1&quot;]], [1, &quot;P1&quot;], [5, 1], [1, 2], [1, &quot;P1&quot;], [1]]
28+
<strong>Output</strong>
29+
[null, 1, 2, [&quot;Task1&quot;, &quot;Task2&quot;], [], 3, [&quot;Task3&quot;, &quot;Task2&quot;], null, null, [&quot;Task3&quot;], [&quot;Task3&quot;, &quot;Task1&quot;]]
30+
31+
<strong>Explanation</strong>
32+
TodoList todoList = new TodoList();
33+
todoList.addTask(1, &quot;Task1&quot;, 50, []); // return 1. This adds a new task for the user with id 1.
34+
todoList.addTask(1, &quot;Task2&quot;, 100, [&quot;P1&quot;]); // return 2. This adds another task for the user with id 1.
35+
todoList.getAllTasks(1); // return [&quot;Task1&quot;, &quot;Task2&quot;]. User 1 has two uncompleted tasks so far.
36+
todoList.getAllTasks(5); // return []. User 5 does not have any tasks so far.
37+
todoList.addTask(1, &quot;Task3&quot;, 30, [&quot;P1&quot;]); // return 3. This adds another task for the user with id 1.
38+
todoList.getTasksForTag(1, &quot;P1&quot;); // return [&quot;Task3&quot;, &quot;Task2&quot;]. This returns the uncompleted tasks that have the tag &quot;P1&quot; for the user with id 1.
39+
todoList.completeTask(5, 1); // This does nothing, since task 1 does not belong to user 5.
40+
todoList.completeTask(1, 2); // This marks task 2 as completed.
41+
todoList.getTasksForTag(1, &quot;P1&quot;); // return [&quot;Task3&quot;]. This returns the uncompleted tasks that have the tag &quot;P1&quot; for the user with id 1.
42+
// Notice that we did not include &quot;Task2&quot; because it is completed now.
43+
todoList.getAllTasks(1); // return [&quot;Task3&quot;, &quot;Task1&quot;]. User 1 now has 2 uncompleted tasks.
44+
45+
</pre>
46+
47+
<p>&nbsp;</p>
48+
<p><strong>Constraints:</strong></p>
49+
50+
<ul>
51+
<li><code>1 &lt;= userId, taskId, dueDate &lt;= 100</code></li>
52+
<li><code>0 &lt;= tags.length &lt;= 100</code></li>
53+
<li><code>1 &lt;= taskDescription.length &lt;= 50</code></li>
54+
<li><code>1 &lt;= tags[i].length, tag.length &lt;= 20</code></li>
55+
<li>All <code>dueDate</code> values are unique.</li>
56+
<li>All the strings consist of lowercase and uppercase English letters and digits.</li>
57+
<li>At most <code>100</code> calls will be made for each method.</li>
58+
</ul>
59+
60+
## 解法
61+
62+
<!-- 这里可写通用的实现逻辑 -->
63+
64+
**方法一:哈希表 + 有序集合**
65+
66+
我们使用哈希表 $tasks$ 记录每个用户的任务集合,其中键为用户 ID,值为一个有序集合,按照任务的截止日期排序。另外用一个变量 $i$ 记录当前任务的 ID。
67+
68+
调用 `addTask` 方法时,我们将任务添加到对应用户的任务集合中,返回任务 ID。此操作的时间复杂度为 $O(\log n)$。
69+
70+
调用 `getAllTasks` 方法时,我们遍历对应用户的任务集合,将未完成的任务的描述添加到结果列表中,返回结果列表。此操作的时间复杂度为 $O(n)$。
71+
72+
调用 `getTasksForTag` 方法时,我们遍历对应用户的任务集合,将未完成的任务的描述添加到结果列表中,返回结果列表。此操作的时间复杂度为 $O(n)$。
73+
74+
调用 `completeTask` 方法时,我们遍历对应用户的任务集合,将任务 ID 为 $taskId$ 的任务标记为已完成。此操作的时间复杂度为 $(n)$。
75+
76+
空间复杂度 $O(n)$。其中 $n$ 为所有任务的数量。
77+
78+
<!-- tabs:start -->
79+
80+
### **Python3**
81+
82+
<!-- 这里可写当前语言的特殊实现逻辑 -->
83+
84+
```python
85+
from sortedcontainers import SortedList
86+
87+
88+
class TodoList:
89+
90+
def __init__(self):
91+
self.i = 1
92+
self.tasks = defaultdict(SortedList)
93+
94+
def addTask(self, userId: int, taskDescription: str, dueDate: int, tags: List[str]) -> int:
95+
taskId = self.i
96+
self.i += 1
97+
self.tasks[userId].add(
98+
[dueDate, taskDescription, set(tags), taskId, False])
99+
return taskId
100+
101+
def getAllTasks(self, userId: int) -> List[str]:
102+
return [x[1] for x in self.tasks[userId] if not x[4]]
103+
104+
def getTasksForTag(self, userId: int, tag: str) -> List[str]:
105+
return [x[1] for x in self.tasks[userId] if not x[4] and tag in x[2]]
106+
107+
def completeTask(self, userId: int, taskId: int) -> None:
108+
for task in self.tasks[userId]:
109+
if task[3] == taskId:
110+
task[4] = True
111+
break
112+
113+
114+
# Your TodoList object will be instantiated and called as such:
115+
# obj = TodoList()
116+
# param_1 = obj.addTask(userId,taskDescription,dueDate,tags)
117+
# param_2 = obj.getAllTasks(userId)
118+
# param_3 = obj.getTasksForTag(userId,tag)
119+
# obj.completeTask(userId,taskId)
120+
```
121+
122+
### **Java**
123+
124+
<!-- 这里可写当前语言的特殊实现逻辑 -->
125+
126+
```java
127+
class Task {
128+
int taskId;
129+
String taskName;
130+
int dueDate;
131+
Set<String> tags;
132+
boolean finish;
133+
134+
public Task(int taskId, String taskName, int dueDate, Set<String> tags) {
135+
this.taskId = taskId;
136+
this.taskName = taskName;
137+
this.dueDate = dueDate;
138+
this.tags = tags;
139+
}
140+
}
141+
142+
class TodoList {
143+
private int i = 1;
144+
private Map<Integer, TreeSet<Task>> tasks = new HashMap<>();
145+
146+
public TodoList() {
147+
148+
}
149+
150+
public int addTask(int userId, String taskDescription, int dueDate, List<String> tags) {
151+
Task task = new Task(i++, taskDescription, dueDate, new HashSet<>(tags));
152+
tasks.computeIfAbsent(userId, k -> new TreeSet<>(Comparator.comparingInt(a -> a.dueDate))).add(task);
153+
return task.taskId;
154+
}
155+
156+
public List<String> getAllTasks(int userId) {
157+
List<String> ans = new ArrayList<>();
158+
if (tasks.containsKey(userId)) {
159+
for (Task task : tasks.get(userId)) {
160+
if (!task.finish) {
161+
ans.add(task.taskName);
162+
}
163+
}
164+
}
165+
return ans;
166+
}
167+
168+
public List<String> getTasksForTag(int userId, String tag) {
169+
List<String> ans = new ArrayList<>();
170+
if (tasks.containsKey(userId)) {
171+
for (Task task : tasks.get(userId)) {
172+
if (task.tags.contains(tag) && !task.finish) {
173+
ans.add(task.taskName);
174+
}
175+
}
176+
}
177+
return ans;
178+
}
179+
180+
public void completeTask(int userId, int taskId) {
181+
if (tasks.containsKey(userId)) {
182+
for (Task task : tasks.get(userId)) {
183+
if (task.taskId == taskId) {
184+
task.finish = true;
185+
break;
186+
}
187+
}
188+
}
189+
}
190+
}
191+
192+
/**
193+
* Your TodoList object will be instantiated and called as such:
194+
* TodoList obj = new TodoList();
195+
* int param_1 = obj.addTask(userId,taskDescription,dueDate,tags);
196+
* List<String> param_2 = obj.getAllTasks(userId);
197+
* List<String> param_3 = obj.getTasksForTag(userId,tag);
198+
* obj.completeTask(userId,taskId);
199+
*/
200+
```
201+
202+
### **C++**
203+
204+
```cpp
205+
206+
```
207+
208+
### **Go**
209+
210+
```go
211+
212+
```
213+
214+
### **...**
215+
216+
```
217+
218+
```
219+
220+
<!-- tabs:end -->

0 commit comments

Comments
 (0)