[](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=149001365&machine=basicLinux32gb&location=SoutheastAsia)
@@ -223,32 +215,18 @@ graph TD;
-## 赞助者
-
-感谢以下个人、组织对本项目的支持和赞助!
-
-
-
-
-
-> "_You help the developer community practice for interviews, and there is nothing better we could ask for._" -- [Alan Yessenbayev](https://opencollective.com/alan-yessenbayev)
-
-## 推荐者
-
-知名互联网科技博主 [@爱可可-爱生活](https://weibo.com/fly51fly) 微博推荐。
-
-
-
## 版权
本项目著作权归 [GitHub 开源社区 Doocs](https://github.com/doocs) 所有,商业转载请联系 @yanglbme 获得授权,非商业转载请注明出处。
-## 联系我们
+## 联系我们 & 支持项目
欢迎各位小伙伴们添加 @yanglbme 的个人微信(微信号:YLB0109),备注 「**leetcode**」。后续我们会创建算法、技术相关的交流群,大家一起交流学习,分享经验,共同进步。
-| |
-| ------------------------------------------------------------------------------------------------------------------------------ |
+如果你觉得这个项目对你有帮助,也欢迎通过微信扫码赞赏我们 ☕️~
+
+| | |
+| -------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
## 许可证
diff --git a/README_EN.md b/README_EN.md
index 4161ac3fb40da..3b461059720a9 100644
--- a/README_EN.md
+++ b/README_EN.md
@@ -1,15 +1,16 @@
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
## Introduction
@@ -184,16 +185,7 @@ I'm looking for long-term contributors/partners to this repo! Send me [PRs](http
1. See [CONTRIBUTING](https://github.com/doocs/.github/blob/main/CONTRIBUTING.md) or [GitHub Help](https://help.github.com/en) for more details.
-
-```mermaid
-graph TD;
- A[LeetCode Repo doocs/leetcode.git] -- 1.Fork --> B[Your GitHub Repo yourusername/leetcode.git];
- B -- 2.Git Clone --> C[Local Machine];
- C -- 3.Create a New Branch & Make Changes --> D[Modify Code Locally];
- D -- 4.Commit & Push to Your Repo --> B;
- B -- 5.Create a Pull Request --> A;
-```
-
+
diff --git a/solution/0000-0099/0033.Search in Rotated Sorted Array/README_EN.md b/solution/0000-0099/0033.Search in Rotated Sorted Array/README_EN.md
index 871221d1251a8..ff3c0a1ead08a 100644
--- a/solution/0000-0099/0033.Search in Rotated Sorted Array/README_EN.md
+++ b/solution/0000-0099/0033.Search in Rotated Sorted Array/README_EN.md
@@ -19,7 +19,7 @@ tags:
There is an integer array nums sorted in ascending order (with distinct values).
-
Prior to being passed to your function, nums is possibly rotated at an unknown pivot index k (1 <= k < nums.length) such that the resulting array is [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]] (0-indexed). For example, [0,1,2,4,5,6,7] might be rotated at pivot index 3 and become [4,5,6,7,0,1,2].
+
Prior to being passed to your function, nums is possibly left rotated at an unknown index k (1 <= k < nums.length) such that the resulting array is [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]] (0-indexed). For example, [0,1,2,4,5,6,7] might be left rotated by 3 indices and become [4,5,6,7,0,1,2].
Given the array numsafter the possible rotation and an integer target, return the index of target if it is in nums, or -1 if it is not in nums.
diff --git a/solution/0000-0099/0045.Jump Game II/README.md b/solution/0000-0099/0045.Jump Game II/README.md
index df5afce25a020..89be5cab7bfd5 100644
--- a/solution/0000-0099/0045.Jump Game II/README.md
+++ b/solution/0000-0099/0045.Jump Game II/README.md
@@ -20,14 +20,14 @@ tags:
每个元素 nums[i] 表示从索引 i 向后跳转的最大长度。换句话说,如果你在索引 i 处,你可以跳转到任意 (i + j) 处:
-
0 <= j <= nums[i]
+
0 <= j <= nums[i] 且
i + j < n
-
返回到达 nums[n - 1] 的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]。
+
返回到达 n - 1 的最小跳跃次数。测试用例保证可以到达 n - 1。
@@ -54,7 +54,7 @@ tags:
1 <= nums.length <= 104
0 <= nums[i] <= 1000
-
题目保证可以到达 nums[n-1]
+
题目保证可以到达 n - 1
diff --git a/solution/0000-0099/0045.Jump Game II/README_EN.md b/solution/0000-0099/0045.Jump Game II/README_EN.md
index 26a6b6242448f..d1f1c273a53a4 100644
--- a/solution/0000-0099/0045.Jump Game II/README_EN.md
+++ b/solution/0000-0099/0045.Jump Game II/README_EN.md
@@ -18,16 +18,16 @@ tags:
-
You are given a 0-indexed array of integers nums of length n. You are initially positioned at nums[0].
+
You are given a 0-indexed array of integers nums of length n. You are initially positioned at index 0.
-
Each element nums[i] represents the maximum length of a forward jump from index i. In other words, if you are at nums[i], you can jump to any nums[i + j] where:
+
Each element nums[i] represents the maximum length of a forward jump from index i. In other words, if you are at index i, you can jump to any index (i + j) where:
0 <= j <= nums[i] and
i + j < n
-
Return the minimum number of jumps to reach nums[n - 1]. The test cases are generated such that you can reach nums[n - 1].
+
Return the minimum number of jumps to reach index n - 1. The test cases are generated such that you can reach index n - 1.
diff --git a/solution/0100-0199/0134.Gas Station/README_EN.md b/solution/0100-0199/0134.Gas Station/README_EN.md
index da715b425416d..2ff776b0c19b4 100644
--- a/solution/0100-0199/0134.Gas Station/README_EN.md
+++ b/solution/0100-0199/0134.Gas Station/README_EN.md
@@ -60,6 +60,7 @@ Therefore, you can't travel around the circuit once no matter where you star
n == gas.length == cost.length
1 <= n <= 105
0 <= gas[i], cost[i] <= 104
+
The input is generated such that the answer is unique.
@@ -203,6 +203,35 @@ function candy(ratings: number[]): number {
}
```
+#### Rust
+
+```rust
+impl Solution {
+ pub fn candy(ratings: Vec) -> i32 {
+ let n = ratings.len();
+ let mut left = vec![1; n];
+ let mut right = vec![1; n];
+
+ for i in 1..n {
+ if ratings[i] > ratings[i - 1] {
+ left[i] = left[i - 1] + 1;
+ }
+ }
+
+ for i in (0..n - 1).rev() {
+ if ratings[i] > ratings[i + 1] {
+ right[i] = right[i + 1] + 1;
+ }
+ }
+
+ ratings.iter()
+ .enumerate()
+ .map(|(i, _)| left[i].max(right[i]) as i32)
+ .sum()
+ }
+}
+```
+
#### C#
```cs
@@ -236,46 +265,4 @@ public class Solution {
-
-
-### 方法二
-
-
-
-#### Java
-
-```java
-class Solution {
- public int candy(int[] ratings) {
- int n = ratings.length;
- int up = 0;
- int down = 0;
- int peak = 0;
- int candies = 1;
- for (int i = 1; i < n; i++) {
- if (ratings[i - 1] < ratings[i]) {
- up++;
- peak = up + 1;
- down = 0;
- candies += peak;
- } else if (ratings[i] == ratings[i - 1]) {
- peak = 0;
- up = 0;
- down = 0;
- candies++;
- } else {
- down++;
- up = 0;
- candies += down + (peak > down ? 0 : 1);
- }
- }
- return candies;
- }
-}
-```
-
-
-
-
-
diff --git a/solution/0100-0199/0135.Candy/README_EN.md b/solution/0100-0199/0135.Candy/README_EN.md
index a37b9e3a1bdb1..af62226fa2b1e 100644
--- a/solution/0100-0199/0135.Candy/README_EN.md
+++ b/solution/0100-0199/0135.Candy/README_EN.md
@@ -202,6 +202,35 @@ function candy(ratings: number[]): number {
}
```
+#### Rust
+
+```rust
+impl Solution {
+ pub fn candy(ratings: Vec) -> i32 {
+ let n = ratings.len();
+ let mut left = vec![1; n];
+ let mut right = vec![1; n];
+
+ for i in 1..n {
+ if ratings[i] > ratings[i - 1] {
+ left[i] = left[i - 1] + 1;
+ }
+ }
+
+ for i in (0..n - 1).rev() {
+ if ratings[i] > ratings[i + 1] {
+ right[i] = right[i + 1] + 1;
+ }
+ }
+
+ ratings.iter()
+ .enumerate()
+ .map(|(i, _)| left[i].max(right[i]) as i32)
+ .sum()
+ }
+}
+```
+
#### C#
```cs
@@ -235,46 +264,4 @@ public class Solution {
-
-
-### Solution 2
-
-
-
-#### Java
-
-```java
-class Solution {
- public int candy(int[] ratings) {
- int n = ratings.length;
- int up = 0;
- int down = 0;
- int peak = 0;
- int candies = 1;
- for (int i = 1; i < n; i++) {
- if (ratings[i - 1] < ratings[i]) {
- up++;
- peak = up + 1;
- down = 0;
- candies += peak;
- } else if (ratings[i] == ratings[i - 1]) {
- peak = 0;
- up = 0;
- down = 0;
- candies++;
- } else {
- down++;
- up = 0;
- candies += down + (peak > down ? 0 : 1);
- }
- }
- return candies;
- }
-}
-```
-
-
-
-
-
diff --git a/solution/0100-0199/0135.Candy/Solution.rs b/solution/0100-0199/0135.Candy/Solution.rs
new file mode 100644
index 0000000000000..17ad371df3999
--- /dev/null
+++ b/solution/0100-0199/0135.Candy/Solution.rs
@@ -0,0 +1,25 @@
+impl Solution {
+ pub fn candy(ratings: Vec) -> i32 {
+ let n = ratings.len();
+ let mut left = vec![1; n];
+ let mut right = vec![1; n];
+
+ for i in 1..n {
+ if ratings[i] > ratings[i - 1] {
+ left[i] = left[i - 1] + 1;
+ }
+ }
+
+ for i in (0..n - 1).rev() {
+ if ratings[i] > ratings[i + 1] {
+ right[i] = right[i + 1] + 1;
+ }
+ }
+
+ ratings
+ .iter()
+ .enumerate()
+ .map(|(i, _)| left[i].max(right[i]) as i32)
+ .sum()
+ }
+}
diff --git a/solution/0100-0199/0135.Candy/Solution2.java b/solution/0100-0199/0135.Candy/Solution2.java
deleted file mode 100644
index 12695f93146a2..0000000000000
--- a/solution/0100-0199/0135.Candy/Solution2.java
+++ /dev/null
@@ -1,27 +0,0 @@
-class Solution {
- public int candy(int[] ratings) {
- int n = ratings.length;
- int up = 0;
- int down = 0;
- int peak = 0;
- int candies = 1;
- for (int i = 1; i < n; i++) {
- if (ratings[i - 1] < ratings[i]) {
- up++;
- peak = up + 1;
- down = 0;
- candies += peak;
- } else if (ratings[i] == ratings[i - 1]) {
- peak = 0;
- up = 0;
- down = 0;
- candies++;
- } else {
- down++;
- up = 0;
- candies += down + (peak > down ? 0 : 1);
- }
- }
- return candies;
- }
-}
\ No newline at end of file
diff --git a/solution/0100-0199/0147.Insertion Sort List/README.md b/solution/0100-0199/0147.Insertion Sort List/README.md
index 5f9c2b84a6d09..2ffa1f3e1ff77 100644
--- a/solution/0100-0199/0147.Insertion Sort List/README.md
+++ b/solution/0100-0199/0147.Insertion Sort List/README.md
@@ -181,6 +181,42 @@ var insertionSortList = function (head) {
};
```
+#### Go
+
+```go
+/**
+ * Definition for singly-linked list.
+ * type ListNode struct {
+ * Val int
+ * Next *ListNode
+ * }
+ */
+func insertionSortList(head *ListNode) *ListNode {
+ if head == nil || head.Next == nil {
+ return head
+ }
+ dummy := &ListNode{head.Val, head}
+ pre, cur := dummy, head
+ for cur != nil {
+ if pre.Val <= cur.Val {
+ pre = cur
+ cur = cur.Next
+ continue
+ }
+ p := dummy
+ for p.Next.Val <= cur.Val {
+ p = p.Next
+ }
+ t := cur.Next
+ cur.Next = p.Next
+ p.Next = cur
+ pre.Next = t
+ cur = t
+ }
+ return dummy.Next
+}
+```
+
diff --git a/solution/0100-0199/0147.Insertion Sort List/README_EN.md b/solution/0100-0199/0147.Insertion Sort List/README_EN.md
index 7fc22c79e3e08..6501ceb997a91 100644
--- a/solution/0100-0199/0147.Insertion Sort List/README_EN.md
+++ b/solution/0100-0199/0147.Insertion Sort List/README_EN.md
@@ -171,6 +171,42 @@ var insertionSortList = function (head) {
};
```
+#### Go
+
+```go
+/**
+ * Definition for singly-linked list.
+ * type ListNode struct {
+ * Val int
+ * Next *ListNode
+ * }
+ */
+func insertionSortList(head *ListNode) *ListNode {
+ if head == nil || head.Next == nil {
+ return head
+ }
+ dummy := &ListNode{head.Val, head}
+ pre, cur := dummy, head
+ for cur != nil {
+ if pre.Val <= cur.Val {
+ pre = cur
+ cur = cur.Next
+ continue
+ }
+ p := dummy
+ for p.Next.Val <= cur.Val {
+ p = p.Next
+ }
+ t := cur.Next
+ cur.Next = p.Next
+ p.Next = cur
+ pre.Next = t
+ cur = t
+ }
+ return dummy.Next
+}
+```
+
diff --git a/solution/0100-0199/0147.Insertion Sort List/Solution.go b/solution/0100-0199/0147.Insertion Sort List/Solution.go
new file mode 100644
index 0000000000000..0bb4987697e5e
--- /dev/null
+++ b/solution/0100-0199/0147.Insertion Sort List/Solution.go
@@ -0,0 +1,31 @@
+/**
+ * Definition for singly-linked list.
+ * type ListNode struct {
+ * Val int
+ * Next *ListNode
+ * }
+ */
+func insertionSortList(head *ListNode) *ListNode {
+ if head == nil || head.Next == nil {
+ return head
+ }
+ dummy := &ListNode{head.Val, head}
+ pre, cur := dummy, head
+ for cur != nil {
+ if pre.Val <= cur.Val {
+ pre = cur
+ cur = cur.Next
+ continue
+ }
+ p := dummy
+ for p.Next.Val <= cur.Val {
+ p = p.Next
+ }
+ t := cur.Next
+ cur.Next = p.Next
+ p.Next = cur
+ pre.Next = t
+ cur = t
+ }
+ return dummy.Next
+}
diff --git a/solution/0100-0199/0177.Nth Highest Salary/README.md b/solution/0100-0199/0177.Nth Highest Salary/README.md
index cc3445e0f5168..74da21d30cbf7 100644
--- a/solution/0100-0199/0177.Nth Highest Salary/README.md
+++ b/solution/0100-0199/0177.Nth Highest Salary/README.md
@@ -25,13 +25,13 @@ tags:
| id | int |
| salary | int |
+-------------+------+
-在 SQL 中,id 是该表的主键。
+id 是该表的主键(列中的值互不相同)。
该表的每一行都包含有关员工工资的信息。
-
查询 Employee 表中第 n 高的工资。如果没有第 n 个最高工资,查询结果应该为 null 。
+
编写一个解决方案查询 Employee 表中第 n 高的 不同 工资。如果少于 n 个不同工资,查询结果应该为 null 。
查询结果格式如下所示。
diff --git a/solution/0100-0199/0177.Nth Highest Salary/README_EN.md b/solution/0100-0199/0177.Nth Highest Salary/README_EN.md
index 37c056f9d75ef..3373a1cd68980 100644
--- a/solution/0100-0199/0177.Nth Highest Salary/README_EN.md
+++ b/solution/0100-0199/0177.Nth Highest Salary/README_EN.md
@@ -31,7 +31,7 @@ Each row of this table contains information about the salary of an employee.
-
Write a solution to find the nth highest salary from the Employee table. If there is no nth highest salary, return null.
+
Write a solution to find the nth highest distinct salary from the Employee table. If there are less than n distinct salaries, return null.
The result format is in the following example.
diff --git a/solution/0100-0199/0184.Department Highest Salary/README.md b/solution/0100-0199/0184.Department Highest Salary/README.md
index f22679744afbb..fe36aca302cbb 100644
--- a/solution/0100-0199/0184.Department Highest Salary/README.md
+++ b/solution/0100-0199/0184.Department Highest Salary/README.md
@@ -114,6 +114,31 @@ WHERE
);
```
+### Pandas
+
+```python
+import pandas as pd
+
+
+def department_highest_salary(
+ employee: pd.DataFrame, department: pd.DataFrame
+) -> pd.DataFrame:
+ # Merge the two tables on departmentId and department id
+ merged = employee.merge(department, left_on='departmentId', right_on='id')
+
+ # Find the maximum salary for each department
+ max_salaries = merged.groupby('departmentId')['salary'].transform('max')
+
+ # Filter employees who have the highest salary in their department
+ top_earners = merged[merged['salary'] == max_salaries]
+
+ # Select required columns and rename them
+ result = top_earners[['name_y', 'name_x', 'salary']].copy()
+ result.columns = ['Department', 'Employee', 'Salary']
+
+ return result
+```
+
diff --git a/solution/0100-0199/0184.Department Highest Salary/README_EN.md b/solution/0100-0199/0184.Department Highest Salary/README_EN.md
index 68aad979846ff..48725a31b1208 100644
--- a/solution/0100-0199/0184.Department Highest Salary/README_EN.md
+++ b/solution/0100-0199/0184.Department Highest Salary/README_EN.md
@@ -116,6 +116,31 @@ WHERE
);
```
+### Pandas
+
+```python
+import pandas as pd
+
+
+def department_highest_salary(
+ employee: pd.DataFrame, department: pd.DataFrame
+) -> pd.DataFrame:
+ # Merge the two tables on departmentId and department id
+ merged = employee.merge(department, left_on='departmentId', right_on='id')
+
+ # Find the maximum salary for each department
+ max_salaries = merged.groupby('departmentId')['salary'].transform('max')
+
+ # Filter employees who have the highest salary in their department
+ top_earners = merged[merged['salary'] == max_salaries]
+
+ # Select required columns and rename them
+ result = top_earners[['name_y', 'name_x', 'salary']].copy()
+ result.columns = ['Department', 'Employee', 'Salary']
+
+ return result
+```
+
diff --git a/solution/0100-0199/0184.Department Highest Salary/Solution.py b/solution/0100-0199/0184.Department Highest Salary/Solution.py
new file mode 100644
index 0000000000000..5b661d76ea904
--- /dev/null
+++ b/solution/0100-0199/0184.Department Highest Salary/Solution.py
@@ -0,0 +1,20 @@
+import pandas as pd
+
+
+def department_highest_salary(
+ employee: pd.DataFrame, department: pd.DataFrame
+) -> pd.DataFrame:
+ # Merge the two tables on departmentId and department id
+ merged = employee.merge(department, left_on='departmentId', right_on='id')
+
+ # Find the maximum salary for each department
+ max_salaries = merged.groupby('departmentId')['salary'].transform('max')
+
+ # Filter employees who have the highest salary in their department
+ top_earners = merged[merged['salary'] == max_salaries]
+
+ # Select required columns and rename them
+ result = top_earners[['name_y', 'name_x', 'salary']].copy()
+ result.columns = ['Department', 'Employee', 'Salary']
+
+ return result
diff --git a/solution/0100-0199/0190.Reverse Bits/README.md b/solution/0100-0199/0190.Reverse Bits/README.md
index e151edf982a68..9bcaffac01ee3 100644
--- a/solution/0100-0199/0190.Reverse Bits/README.md
+++ b/solution/0100-0199/0190.Reverse Bits/README.md
@@ -23,33 +23,72 @@ tags:
Note that in some languages, such as Java, there is no unsigned integer type. In this case, both input and output will be given as a signed integer type. They should not affect your implementation, as the integer's internal binary representation is the same, whether it is signed or unsigned.
-
In Java, the compiler represents the signed integers using 2's complement notation. Therefore, in Example 2 above, the input represents the signed integer -3 and the output represents the signed integer -1073741825.
-Input: n = 00000010100101000001111010011100
-Output: 964176192 (00111001011110000010100101000000)
-Explanation: The input binary string 00000010100101000001111010011100 represents the unsigned integer 43261596, so return 964176192 which its binary representation is 00111001011110000010100101000000.
-
+
+
Input:n = 43261596
+
+
Output:964176192
+
+
Explanation:
+
+
+
+
+
Integer
+
Binary
+
+
+
43261596
+
00000010100101000001111010011100
+
+
+
964176192
+
00111001011110000010100101000000
+
+
+
+
Example 2:
-
-Input: n = 11111111111111111111111111111101
-Output: 3221225471 (10111111111111111111111111111111)
-Explanation: The input binary string 11111111111111111111111111111101 represents the unsigned integer 4294967293, so return 3221225471 which its binary representation is 10111111111111111111111111111111.
-
+
+
Input:n = 2147483644
+
+
Output:1073741822
+
+
Explanation:
+
+
+
+
+
Integer
+
Binary
+
+
+
2147483644
+
01111111111111111111111111111100
+
+
+
1073741822
+
00111111111111111111111111111110
+
+
+
+
Constraints:
-
The input must be a binary string of length 32
+
0 <= n <= 231 - 2
+
n is even.
diff --git a/solution/0200-0299/0206.Reverse Linked List/README.md b/solution/0200-0299/0206.Reverse Linked List/README.md
index 13c9e67956f8a..3a47400b7a3c0 100644
--- a/solution/0200-0299/0206.Reverse Linked List/README.md
+++ b/solution/0200-0299/0206.Reverse Linked List/README.md
@@ -67,9 +67,9 @@ tags:
### 方法一:头插法
-创建虚拟头节点 $dummy$,遍历链表,将每个节点依次插入 $dummy$ 的下一个节点。遍历结束,返回 $dummy.next$。
+我们创建一个虚拟头节点 $\textit{dummy}$,然后遍历链表,将每个节点依次插入 $\textit{dummy}$ 的下一个节点。遍历结束,返回 $\textit{dummy.next}$。
-时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为链表的长度。
+时间复杂度 $O(n)$,其中 $n$ 为链表的长度。空间复杂度 $O(1)$。
@@ -279,15 +279,15 @@ var reverseList = function (head) {
*/
public class Solution {
public ListNode ReverseList(ListNode head) {
- ListNode pre = null;
- for (ListNode p = head; p != null;)
- {
- ListNode t = p.next;
- p.next = pre;
- pre = p;
- p = t;
+ ListNode dummy = new ListNode();
+ ListNode curr = head;
+ while (curr != null) {
+ ListNode next = curr.next;
+ curr.next = dummy.next;
+ dummy.next = curr;
+ curr = next;
}
- return pre;
+ return dummy.next;
}
}
```
@@ -466,6 +466,33 @@ impl Solution {
}
```
+#### C#
+
+```cs
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public int val;
+ * public ListNode next;
+ * public ListNode(int val=0, ListNode next=null) {
+ * this.val = val;
+ * this.next = next;
+ * }
+ * }
+ */
+public class Solution {
+ public ListNode ReverseList(ListNode head) {
+ if (head == null || head.next == null) {
+ return head;
+ }
+ ListNode ans = ReverseList(head.next);
+ head.next.next = head;
+ head.next = null;
+ return ans;
+ }
+}
+```
+
diff --git a/solution/0200-0299/0206.Reverse Linked List/README_EN.md b/solution/0200-0299/0206.Reverse Linked List/README_EN.md
index 6ef93b442d5a7..298960c2eaa3b 100644
--- a/solution/0200-0299/0206.Reverse Linked List/README_EN.md
+++ b/solution/0200-0299/0206.Reverse Linked List/README_EN.md
@@ -58,7 +58,11 @@ tags:
-### Solution 1
+### Solution 1: Head Insertion Method
+
+We create a dummy node $\textit{dummy}$, then traverse the linked list and insert each node after the $\textit{dummy}$ node. After traversal, return $\textit{dummy.next}$.
+
+The time complexity is $O(n)$, where $n$ is the length of the linked list. The space complexity is $O(1)$.
@@ -268,15 +272,15 @@ var reverseList = function (head) {
*/
public class Solution {
public ListNode ReverseList(ListNode head) {
- ListNode pre = null;
- for (ListNode p = head; p != null;)
- {
- ListNode t = p.next;
- p.next = pre;
- pre = p;
- p = t;
+ ListNode dummy = new ListNode();
+ ListNode curr = head;
+ while (curr != null) {
+ ListNode next = curr.next;
+ curr.next = dummy.next;
+ dummy.next = curr;
+ curr = next;
}
- return pre;
+ return dummy.next;
}
}
```
@@ -287,7 +291,11 @@ public class Solution {
-### Solution 2
+### Solution 2: Recursion
+
+We recursively reverse all nodes from the second node to the end of the list, then attach the $head$ to the end of the reversed list.
+
+The time complexity is $O(n)$, and the space complexity is $O(n)$. Where $n$ is the length of the linked list.
@@ -451,6 +459,33 @@ impl Solution {
}
```
+#### C#
+
+```cs
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public int val;
+ * public ListNode next;
+ * public ListNode(int val=0, ListNode next=null) {
+ * this.val = val;
+ * this.next = next;
+ * }
+ * }
+ */
+public class Solution {
+ public ListNode ReverseList(ListNode head) {
+ if (head == null || head.next == null) {
+ return head;
+ }
+ ListNode ans = ReverseList(head.next);
+ head.next.next = head;
+ head.next = null;
+ return ans;
+ }
+}
+```
+
diff --git a/solution/0200-0299/0206.Reverse Linked List/Solution.cs b/solution/0200-0299/0206.Reverse Linked List/Solution.cs
index fd70b47359d14..41cc12eb05aee 100644
--- a/solution/0200-0299/0206.Reverse Linked List/Solution.cs
+++ b/solution/0200-0299/0206.Reverse Linked List/Solution.cs
@@ -11,14 +11,14 @@
*/
public class Solution {
public ListNode ReverseList(ListNode head) {
- ListNode pre = null;
- for (ListNode p = head; p != null;)
- {
- ListNode t = p.next;
- p.next = pre;
- pre = p;
- p = t;
+ ListNode dummy = new ListNode();
+ ListNode curr = head;
+ while (curr != null) {
+ ListNode next = curr.next;
+ curr.next = dummy.next;
+ dummy.next = curr;
+ curr = next;
}
- return pre;
+ return dummy.next;
}
-}
+}
\ No newline at end of file
diff --git a/solution/0200-0299/0206.Reverse Linked List/Solution2.cs b/solution/0200-0299/0206.Reverse Linked List/Solution2.cs
new file mode 100644
index 0000000000000..c3b57890bfd3f
--- /dev/null
+++ b/solution/0200-0299/0206.Reverse Linked List/Solution2.cs
@@ -0,0 +1,22 @@
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ * public int val;
+ * public ListNode next;
+ * public ListNode(int val=0, ListNode next=null) {
+ * this.val = val;
+ * this.next = next;
+ * }
+ * }
+ */
+public class Solution {
+ public ListNode ReverseList(ListNode head) {
+ if (head == null || head.next == null) {
+ return head;
+ }
+ ListNode ans = ReverseList(head.next);
+ head.next.next = head;
+ head.next = null;
+ return ans;
+ }
+}
\ No newline at end of file
diff --git a/solution/0200-0299/0228.Summary Ranges/README.md b/solution/0200-0299/0228.Summary Ranges/README.md
index 116f2802681e4..6454d51662d39 100644
--- a/solution/0200-0299/0228.Summary Ranges/README.md
+++ b/solution/0200-0299/0228.Summary Ranges/README.md
@@ -18,7 +18,9 @@ tags:
+
## 解法
diff --git a/solution/0200-0299/0252.Meeting Rooms/README.md b/solution/0200-0299/0252.Meeting Rooms/README.md
index db5c3a47d17bf..6b44b73110318 100644
--- a/solution/0200-0299/0252.Meeting Rooms/README.md
+++ b/solution/0200-0299/0252.Meeting Rooms/README.md
@@ -53,9 +53,9 @@ tags:
### 方法一:排序
-我们将会议按照开始时间进行排序,然后遍历排序后的会议,如果当前会议的开始时间小于前一个会议的结束时间,则说明两个会议有重叠,返回 `false` 即可。
+我们将会议按照开始时间进行排序,然后遍历排序后的会议,如果当前会议的开始时间小于前一个会议的结束时间,则说明两个会议有重叠,返回 $\text{false}$,否则继续遍历。
-遍历结束后,返回 `true`。
+如果遍历结束都没有发现重叠的会议,则返回 $\text{true}$。
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(\log n)$。其中 $n$ 为会议数量。
@@ -77,9 +77,7 @@ class Solution {
public boolean canAttendMeetings(int[][] intervals) {
Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
for (int i = 1; i < intervals.length; ++i) {
- var a = intervals[i - 1];
- var b = intervals[i];
- if (a[1] > b[0]) {
+ if (intervals[i - 1][1] > intervals[i][0]) {
return false;
}
}
@@ -94,11 +92,11 @@ class Solution {
class Solution {
public:
bool canAttendMeetings(vector>& intervals) {
- sort(intervals.begin(), intervals.end(), [](const vector& a, const vector& b) {
+ ranges::sort(intervals, [](const auto& a, const auto& b) {
return a[0] < b[0];
});
for (int i = 1; i < intervals.size(); ++i) {
- if (intervals[i][0] < intervals[i - 1][1]) {
+ if (intervals[i - 1][1] > intervals[i][0]) {
return false;
}
}
@@ -141,32 +139,13 @@ function canAttendMeetings(intervals: number[][]): boolean {
```rust
impl Solution {
- #[allow(dead_code)]
- pub fn can_attend_meetings(intervals: Vec>) -> bool {
- if intervals.len() == 1 {
- return true;
- }
-
- let mut intervals = intervals;
-
- // Sort the intervals vector
- intervals.sort_by(|lhs, rhs| lhs[0].cmp(&rhs[0]));
-
- let mut end = -1;
-
- // Begin traverse
- for p in &intervals {
- if end == -1 {
- // This is the first pair
- end = p[1];
- continue;
- }
- if p[0] < end {
+ pub fn can_attend_meetings(mut intervals: Vec>) -> bool {
+ intervals.sort_by(|a, b| a[0].cmp(&b[0]));
+ for i in 1..intervals.len() {
+ if intervals[i - 1][1] > intervals[i][0] {
return false;
}
- end = p[1];
}
-
true
}
}
diff --git a/solution/0200-0299/0252.Meeting Rooms/README_EN.md b/solution/0200-0299/0252.Meeting Rooms/README_EN.md
index e052d217a0a34..3553a9ea56eee 100644
--- a/solution/0200-0299/0252.Meeting Rooms/README_EN.md
+++ b/solution/0200-0299/0252.Meeting Rooms/README_EN.md
@@ -42,7 +42,13 @@ tags:
-### Solution 1
+### Solution 1: Sorting
+
+We sort the meetings based on their start times, and then iterate through the sorted meetings. If the start time of the current meeting is less than the end time of the previous meeting, it indicates that there is an overlap between the two meetings, and we return `false`. Otherwise, we continue iterating.
+
+If no overlap is found by the end of the iteration, we return `true`.
+
+The time complexity is $O(n \times \log n)$, and the space complexity is $O(\log n)$, where $n$ is the number of meetings.
@@ -62,9 +68,7 @@ class Solution {
public boolean canAttendMeetings(int[][] intervals) {
Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
for (int i = 1; i < intervals.length; ++i) {
- var a = intervals[i - 1];
- var b = intervals[i];
- if (a[1] > b[0]) {
+ if (intervals[i - 1][1] > intervals[i][0]) {
return false;
}
}
@@ -79,11 +83,11 @@ class Solution {
class Solution {
public:
bool canAttendMeetings(vector>& intervals) {
- sort(intervals.begin(), intervals.end(), [](const vector& a, const vector& b) {
+ ranges::sort(intervals, [](const auto& a, const auto& b) {
return a[0] < b[0];
});
for (int i = 1; i < intervals.size(); ++i) {
- if (intervals[i][0] < intervals[i - 1][1]) {
+ if (intervals[i - 1][1] > intervals[i][0]) {
return false;
}
}
@@ -126,32 +130,13 @@ function canAttendMeetings(intervals: number[][]): boolean {
```rust
impl Solution {
- #[allow(dead_code)]
- pub fn can_attend_meetings(intervals: Vec>) -> bool {
- if intervals.len() == 1 {
- return true;
- }
-
- let mut intervals = intervals;
-
- // Sort the intervals vector
- intervals.sort_by(|lhs, rhs| lhs[0].cmp(&rhs[0]));
-
- let mut end = -1;
-
- // Begin traverse
- for p in &intervals {
- if end == -1 {
- // This is the first pair
- end = p[1];
- continue;
- }
- if p[0] < end {
+ pub fn can_attend_meetings(mut intervals: Vec>) -> bool {
+ intervals.sort_by(|a, b| a[0].cmp(&b[0]));
+ for i in 1..intervals.len() {
+ if intervals[i - 1][1] > intervals[i][0] {
return false;
}
- end = p[1];
}
-
true
}
}
diff --git a/solution/0200-0299/0252.Meeting Rooms/Solution.cpp b/solution/0200-0299/0252.Meeting Rooms/Solution.cpp
index 7e6b6657fe2e5..9fca6aeed42e3 100644
--- a/solution/0200-0299/0252.Meeting Rooms/Solution.cpp
+++ b/solution/0200-0299/0252.Meeting Rooms/Solution.cpp
@@ -1,14 +1,14 @@
class Solution {
public:
bool canAttendMeetings(vector>& intervals) {
- sort(intervals.begin(), intervals.end(), [](const vector& a, const vector& b) {
+ ranges::sort(intervals, [](const auto& a, const auto& b) {
return a[0] < b[0];
});
for (int i = 1; i < intervals.size(); ++i) {
- if (intervals[i][0] < intervals[i - 1][1]) {
+ if (intervals[i - 1][1] > intervals[i][0]) {
return false;
}
}
return true;
}
-};
\ No newline at end of file
+};
diff --git a/solution/0200-0299/0252.Meeting Rooms/Solution.java b/solution/0200-0299/0252.Meeting Rooms/Solution.java
index 565b05b05f2f8..008f531dfad17 100644
--- a/solution/0200-0299/0252.Meeting Rooms/Solution.java
+++ b/solution/0200-0299/0252.Meeting Rooms/Solution.java
@@ -2,12 +2,10 @@ class Solution {
public boolean canAttendMeetings(int[][] intervals) {
Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
for (int i = 1; i < intervals.length; ++i) {
- var a = intervals[i - 1];
- var b = intervals[i];
- if (a[1] > b[0]) {
+ if (intervals[i - 1][1] > intervals[i][0]) {
return false;
}
}
return true;
}
-}
\ No newline at end of file
+}
diff --git a/solution/0200-0299/0252.Meeting Rooms/Solution.rs b/solution/0200-0299/0252.Meeting Rooms/Solution.rs
index 1ee4bd2d2cc4a..a81f3d2fc39a5 100644
--- a/solution/0200-0299/0252.Meeting Rooms/Solution.rs
+++ b/solution/0200-0299/0252.Meeting Rooms/Solution.rs
@@ -1,30 +1,11 @@
impl Solution {
- #[allow(dead_code)]
- pub fn can_attend_meetings(intervals: Vec>) -> bool {
- if intervals.len() == 1 {
- return true;
- }
-
- let mut intervals = intervals;
-
- // Sort the intervals vector
- intervals.sort_by(|lhs, rhs| lhs[0].cmp(&rhs[0]));
-
- let mut end = -1;
-
- // Begin traverse
- for p in &intervals {
- if end == -1 {
- // This is the first pair
- end = p[1];
- continue;
- }
- if p[0] < end {
+ pub fn can_attend_meetings(mut intervals: Vec>) -> bool {
+ intervals.sort_by(|a, b| a[0].cmp(&b[0]));
+ for i in 1..intervals.len() {
+ if intervals[i - 1][1] > intervals[i][0] {
return false;
}
- end = p[1];
}
-
true
}
}
diff --git a/solution/0200-0299/0253.Meeting Rooms II/README.md b/solution/0200-0299/0253.Meeting Rooms II/README.md
index c330c2024b93d..72e3b0353c53f 100644
--- a/solution/0200-0299/0253.Meeting Rooms II/README.md
+++ b/solution/0200-0299/0253.Meeting Rooms II/README.md
@@ -56,6 +56,169 @@ tags:
### 方法一:差分数组
+我们可以用差分数组来实现。
+
+我们首先找到所有会议的最大结束时间,记为 $m$,然后创建一个长度为 $m + 1$ 的差分数组 $d$,将每个会议的开始时间和结束时间分别加到差分数组的对应位置上,即 $d[l] = d[l] + 1$,而 $d[r] = d[r] - 1$。
+
+然后,我们计算差分数组的前缀和,找出前缀和的最大值,即为所需会议室的最小数量。
+
+时间复杂度 $O(n + m)$,空间复杂度 $O(m)$。其中 $n$ 和 $m$ 分别为会议数量和最大结束时间。
+
+
+
+#### Python3
+
+```python
+class Solution:
+ def minMeetingRooms(self, intervals: List[List[int]]) -> int:
+ m = max(e[1] for e in intervals)
+ d = [0] * (m + 1)
+ for l, r in intervals:
+ d[l] += 1
+ d[r] -= 1
+ ans = s = 0
+ for v in d:
+ s += v
+ ans = max(ans, s)
+ return ans
+```
+
+#### Java
+
+```java
+class Solution {
+ public int minMeetingRooms(int[][] intervals) {
+ int m = 0;
+ for (var e : intervals) {
+ m = Math.max(m, e[1]);
+ }
+ int[] d = new int[m + 1];
+ for (var e : intervals) {
+ ++d[e[0]];
+ --d[e[1]];
+ }
+ int ans = 0, s = 0;
+ for (int v : d) {
+ s += v;
+ ans = Math.max(ans, s);
+ }
+ return ans;
+ }
+}
+```
+
+#### C++
+
+```cpp
+class Solution {
+public:
+ int minMeetingRooms(vector>& intervals) {
+ int m = 0;
+ for (const auto& e : intervals) {
+ m = max(m, e[1]);
+ }
+ vector d(m + 1);
+ for (const auto& e : intervals) {
+ d[e[0]]++;
+ d[e[1]]--;
+ }
+ int ans = 0, s = 0;
+ for (int v : d) {
+ s += v;
+ ans = max(ans, s);
+ }
+ return ans;
+ }
+};
+```
+
+#### Go
+
+```go
+func minMeetingRooms(intervals [][]int) (ans int) {
+ m := 0
+ for _, e := range intervals {
+ m = max(m, e[1])
+ }
+
+ d := make([]int, m+1)
+ for _, e := range intervals {
+ d[e[0]]++
+ d[e[1]]--
+ }
+
+ s := 0
+ for _, v := range d {
+ s += v
+ ans = max(ans, s)
+ }
+ return
+}
+```
+
+#### TypeScript
+
+```ts
+function minMeetingRooms(intervals: number[][]): number {
+ const m = Math.max(...intervals.map(([_, r]) => r));
+ const d: number[] = Array(m + 1).fill(0);
+ for (const [l, r] of intervals) {
+ d[l]++;
+ d[r]--;
+ }
+ let [ans, s] = [0, 0];
+ for (const v of d) {
+ s += v;
+ ans = Math.max(ans, s);
+ }
+ return ans;
+}
+```
+
+#### Rust
+
+```rust
+impl Solution {
+ pub fn min_meeting_rooms(intervals: Vec>) -> i32 {
+ let mut m = 0;
+ for e in &intervals {
+ m = m.max(e[1]);
+ }
+
+ let mut d = vec![0; (m + 1) as usize];
+ for e in intervals {
+ d[e[0] as usize] += 1;
+ d[e[1] as usize] -= 1;
+ }
+
+ let mut ans = 0;
+ let mut s = 0;
+ for v in d {
+ s += v;
+ ans = ans.max(s);
+ }
+
+ ans
+ }
+}
+```
+
+
+
+
+
+
+
+### 方法二:差分(哈希表)
+
+如果题目中的会议时间跨度很大,那么我们可以使用哈希表来代替差分数组。
+
+我们首先创建一个哈希表 $d$,将每个会议的开始时间和结束时间分别加到哈希表的对应位置上,即 $d[l] = d[l] + 1$,而 $d[r] = d[r] - 1$。
+
+然后,我们将哈希表按照键进行排序,计算哈希表的前缀和,找出前缀和的最大值,即为所需会议室的最小数量。
+
+时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为会议数量。
+
#### Python3
@@ -63,11 +226,15 @@ tags:
```python
class Solution:
def minMeetingRooms(self, intervals: List[List[int]]) -> int:
- delta = [0] * 1000010
- for start, end in intervals:
- delta[start] += 1
- delta[end] -= 1
- return max(accumulate(delta))
+ d = defaultdict(int)
+ for l, r in intervals:
+ d[l] += 1
+ d[r] -= 1
+ ans = s = 0
+ for _, v in sorted(d.items()):
+ s += v
+ ans = max(ans, s)
+ return ans
```
#### Java
@@ -75,18 +242,17 @@ class Solution:
```java
class Solution {
public int minMeetingRooms(int[][] intervals) {
- int n = 1000010;
- int[] delta = new int[n];
- for (int[] e : intervals) {
- ++delta[e[0]];
- --delta[e[1]];
+ Map d = new TreeMap<>();
+ for (var e : intervals) {
+ d.merge(e[0], 1, Integer::sum);
+ d.merge(e[1], -1, Integer::sum);
}
- int res = delta[0];
- for (int i = 1; i < n; ++i) {
- delta[i] += delta[i - 1];
- res = Math.max(res, delta[i]);
+ int ans = 0, s = 0;
+ for (var e : d.values()) {
+ s += e;
+ ans = Math.max(ans, s);
}
- return res;
+ return ans;
}
}
```
@@ -97,16 +263,17 @@ class Solution {
class Solution {
public:
int minMeetingRooms(vector>& intervals) {
- int n = 1000010;
- vector delta(n);
- for (auto e : intervals) {
- ++delta[e[0]];
- --delta[e[1]];
+ map d;
+ for (const auto& e : intervals) {
+ d[e[0]]++;
+ d[e[1]]--;
}
- for (int i = 0; i < n - 1; ++i) {
- delta[i + 1] += delta[i];
+ int ans = 0, s = 0;
+ for (auto& [_, v] : d) {
+ s += v;
+ ans = max(ans, s);
}
- return *max_element(delta.begin(), delta.end());
+ return ans;
}
};
```
@@ -114,56 +281,75 @@ public:
#### Go
```go
-func minMeetingRooms(intervals [][]int) int {
- n := 1000010
- delta := make([]int, n)
+func minMeetingRooms(intervals [][]int) (ans int) {
+ d := make(map[int]int)
for _, e := range intervals {
- delta[e[0]]++
- delta[e[1]]--
+ d[e[0]]++
+ d[e[1]]--
+ }
+
+ keys := make([]int, 0, len(d))
+ for k := range d {
+ keys = append(keys, k)
}
- for i := 1; i < n; i++ {
- delta[i] += delta[i-1]
+ sort.Ints(keys)
+
+ s := 0
+ for _, k := range keys {
+ s += d[k]
+ ans = max(ans, s)
}
- return slices.Max(delta)
+ return
+}
+```
+
+#### TypeScript
+
+```ts
+function minMeetingRooms(intervals: number[][]): number {
+ const d: { [key: number]: number } = {};
+ for (const [l, r] of intervals) {
+ d[l] = (d[l] || 0) + 1;
+ d[r] = (d[r] || 0) - 1;
+ }
+
+ let [ans, s] = [0, 0];
+ const keys = Object.keys(d)
+ .map(Number)
+ .sort((a, b) => a - b);
+ for (const k of keys) {
+ s += d[k];
+ ans = Math.max(ans, s);
+ }
+ return ans;
}
```
#### Rust
```rust
-use std::{cmp::Reverse, collections::BinaryHeap};
+use std::collections::HashMap;
impl Solution {
- #[allow(dead_code)]
pub fn min_meeting_rooms(intervals: Vec>) -> i32 {
- // The min heap that stores the earliest ending time among all meeting rooms
- let mut pq = BinaryHeap::new();
- let mut intervals = intervals;
- let n = intervals.len();
-
- // Let's first sort the intervals vector
- intervals.sort_by(|lhs, rhs| lhs[0].cmp(&rhs[0]));
-
- // Push the first end time to the heap
- pq.push(Reverse(intervals[0][1]));
-
- // Traverse the intervals vector
- for i in 1..n {
- // Get the current top element from the heap
- if let Some(Reverse(end_time)) = pq.pop() {
- if end_time <= intervals[i][0] {
- // If the end time is early than the current begin time
- let new_end_time = intervals[i][1];
- pq.push(Reverse(new_end_time));
- } else {
- // Otherwise, push the end time back and we also need a new room
- pq.push(Reverse(end_time));
- pq.push(Reverse(intervals[i][1]));
- }
- }
+ let mut d: HashMap = HashMap::new();
+ for interval in intervals {
+ let (l, r) = (interval[0], interval[1]);
+ *d.entry(l).or_insert(0) += 1;
+ *d.entry(r).or_insert(0) -= 1;
+ }
+
+ let mut times: Vec = d.keys().cloned().collect();
+ times.sort();
+
+ let mut ans = 0;
+ let mut s = 0;
+ for time in times {
+ s += d[&time];
+ ans = ans.max(s);
}
- pq.len() as i32
+ ans
}
}
```
diff --git a/solution/0200-0299/0253.Meeting Rooms II/README_EN.md b/solution/0200-0299/0253.Meeting Rooms II/README_EN.md
index 819e7009ce22e..9065c37a97deb 100644
--- a/solution/0200-0299/0253.Meeting Rooms II/README_EN.md
+++ b/solution/0200-0299/0253.Meeting Rooms II/README_EN.md
@@ -45,7 +45,170 @@ tags:
-### Solution 1
+### Solution 1: Difference Array
+
+We can implement this using a difference array.
+
+First, we find the maximum end time of all the meetings, denoted as $m$. Then, we create a difference array $d$ of length $m + 1$. For each meeting, we add to the corresponding positions in the difference array: $d[l] = d[l] + 1$ for the start time, and $d[r] = d[r] - 1$ for the end time.
+
+Next, we calculate the prefix sum of the difference array and find the maximum value of the prefix sum, which represents the minimum number of meeting rooms required.
+
+The time complexity is $O(n + m)$ and the space complexity is $O(m)$, where $n$ is the number of meetings and $m$ is the maximum end time.
+
+
+
+#### Python3
+
+```python
+class Solution:
+ def minMeetingRooms(self, intervals: List[List[int]]) -> int:
+ m = max(e[1] for e in intervals)
+ d = [0] * (m + 1)
+ for l, r in intervals:
+ d[l] += 1
+ d[r] -= 1
+ ans = s = 0
+ for v in d:
+ s += v
+ ans = max(ans, s)
+ return ans
+```
+
+#### Java
+
+```java
+class Solution {
+ public int minMeetingRooms(int[][] intervals) {
+ int m = 0;
+ for (var e : intervals) {
+ m = Math.max(m, e[1]);
+ }
+ int[] d = new int[m + 1];
+ for (var e : intervals) {
+ ++d[e[0]];
+ --d[e[1]];
+ }
+ int ans = 0, s = 0;
+ for (int v : d) {
+ s += v;
+ ans = Math.max(ans, s);
+ }
+ return ans;
+ }
+}
+```
+
+#### C++
+
+```cpp
+class Solution {
+public:
+ int minMeetingRooms(vector>& intervals) {
+ int m = 0;
+ for (const auto& e : intervals) {
+ m = max(m, e[1]);
+ }
+ vector d(m + 1);
+ for (const auto& e : intervals) {
+ d[e[0]]++;
+ d[e[1]]--;
+ }
+ int ans = 0, s = 0;
+ for (int v : d) {
+ s += v;
+ ans = max(ans, s);
+ }
+ return ans;
+ }
+};
+```
+
+#### Go
+
+```go
+func minMeetingRooms(intervals [][]int) (ans int) {
+ m := 0
+ for _, e := range intervals {
+ m = max(m, e[1])
+ }
+
+ d := make([]int, m+1)
+ for _, e := range intervals {
+ d[e[0]]++
+ d[e[1]]--
+ }
+
+ s := 0
+ for _, v := range d {
+ s += v
+ ans = max(ans, s)
+ }
+ return
+}
+```
+
+#### TypeScript
+
+```ts
+function minMeetingRooms(intervals: number[][]): number {
+ const m = Math.max(...intervals.map(([_, r]) => r));
+ const d: number[] = Array(m + 1).fill(0);
+ for (const [l, r] of intervals) {
+ d[l]++;
+ d[r]--;
+ }
+ let [ans, s] = [0, 0];
+ for (const v of d) {
+ s += v;
+ ans = Math.max(ans, s);
+ }
+ return ans;
+}
+```
+
+#### Rust
+
+```rust
+impl Solution {
+ pub fn min_meeting_rooms(intervals: Vec>) -> i32 {
+ let mut m = 0;
+ for e in &intervals {
+ m = m.max(e[1]);
+ }
+
+ let mut d = vec![0; (m + 1) as usize];
+ for e in intervals {
+ d[e[0] as usize] += 1;
+ d[e[1] as usize] -= 1;
+ }
+
+ let mut ans = 0;
+ let mut s = 0;
+ for v in d {
+ s += v;
+ ans = ans.max(s);
+ }
+
+ ans
+ }
+}
+```
+
+
+
+
+
+
+
+### Solution 2: Difference (Hash Map)
+
+If the meeting times span a large range, we can use a hash map instead of a difference array.
+
+First, we create a hash map $d$, where we add to the corresponding positions for each meeting's start time and end time: $d[l] = d[l] + 1$ for the start time, and $d[r] = d[r] - 1$ for the end time.
+
+Then, we sort the hash map by its keys, calculate the prefix sum of the hash map, and find the maximum value of the prefix sum, which represents the minimum number of meeting rooms required.
+
+The time complexity is $O(n \times \log n)$ and the space complexity is $O(n)$, where $n$ is the number of meetings.
@@ -54,11 +217,15 @@ tags:
```python
class Solution:
def minMeetingRooms(self, intervals: List[List[int]]) -> int:
- delta = [0] * 1000010
- for start, end in intervals:
- delta[start] += 1
- delta[end] -= 1
- return max(accumulate(delta))
+ d = defaultdict(int)
+ for l, r in intervals:
+ d[l] += 1
+ d[r] -= 1
+ ans = s = 0
+ for _, v in sorted(d.items()):
+ s += v
+ ans = max(ans, s)
+ return ans
```
#### Java
@@ -66,18 +233,17 @@ class Solution:
```java
class Solution {
public int minMeetingRooms(int[][] intervals) {
- int n = 1000010;
- int[] delta = new int[n];
- for (int[] e : intervals) {
- ++delta[e[0]];
- --delta[e[1]];
+ Map d = new TreeMap<>();
+ for (var e : intervals) {
+ d.merge(e[0], 1, Integer::sum);
+ d.merge(e[1], -1, Integer::sum);
}
- int res = delta[0];
- for (int i = 1; i < n; ++i) {
- delta[i] += delta[i - 1];
- res = Math.max(res, delta[i]);
+ int ans = 0, s = 0;
+ for (var e : d.values()) {
+ s += e;
+ ans = Math.max(ans, s);
}
- return res;
+ return ans;
}
}
```
@@ -88,16 +254,17 @@ class Solution {
class Solution {
public:
int minMeetingRooms(vector>& intervals) {
- int n = 1000010;
- vector delta(n);
- for (auto e : intervals) {
- ++delta[e[0]];
- --delta[e[1]];
+ map d;
+ for (const auto& e : intervals) {
+ d[e[0]]++;
+ d[e[1]]--;
}
- for (int i = 0; i < n - 1; ++i) {
- delta[i + 1] += delta[i];
+ int ans = 0, s = 0;
+ for (auto& [_, v] : d) {
+ s += v;
+ ans = max(ans, s);
}
- return *max_element(delta.begin(), delta.end());
+ return ans;
}
};
```
@@ -105,56 +272,75 @@ public:
#### Go
```go
-func minMeetingRooms(intervals [][]int) int {
- n := 1000010
- delta := make([]int, n)
+func minMeetingRooms(intervals [][]int) (ans int) {
+ d := make(map[int]int)
for _, e := range intervals {
- delta[e[0]]++
- delta[e[1]]--
+ d[e[0]]++
+ d[e[1]]--
+ }
+
+ keys := make([]int, 0, len(d))
+ for k := range d {
+ keys = append(keys, k)
}
- for i := 1; i < n; i++ {
- delta[i] += delta[i-1]
+ sort.Ints(keys)
+
+ s := 0
+ for _, k := range keys {
+ s += d[k]
+ ans = max(ans, s)
}
- return slices.Max(delta)
+ return
+}
+```
+
+#### TypeScript
+
+```ts
+function minMeetingRooms(intervals: number[][]): number {
+ const d: { [key: number]: number } = {};
+ for (const [l, r] of intervals) {
+ d[l] = (d[l] || 0) + 1;
+ d[r] = (d[r] || 0) - 1;
+ }
+
+ let [ans, s] = [0, 0];
+ const keys = Object.keys(d)
+ .map(Number)
+ .sort((a, b) => a - b);
+ for (const k of keys) {
+ s += d[k];
+ ans = Math.max(ans, s);
+ }
+ return ans;
}
```
#### Rust
```rust
-use std::{cmp::Reverse, collections::BinaryHeap};
+use std::collections::HashMap;
impl Solution {
- #[allow(dead_code)]
pub fn min_meeting_rooms(intervals: Vec>) -> i32 {
- // The min heap that stores the earliest ending time among all meeting rooms
- let mut pq = BinaryHeap::new();
- let mut intervals = intervals;
- let n = intervals.len();
-
- // Let's first sort the intervals vector
- intervals.sort_by(|lhs, rhs| lhs[0].cmp(&rhs[0]));
-
- // Push the first end time to the heap
- pq.push(Reverse(intervals[0][1]));
-
- // Traverse the intervals vector
- for i in 1..n {
- // Get the current top element from the heap
- if let Some(Reverse(end_time)) = pq.pop() {
- if end_time <= intervals[i][0] {
- // If the end time is early than the current begin time
- let new_end_time = intervals[i][1];
- pq.push(Reverse(new_end_time));
- } else {
- // Otherwise, push the end time back and we also need a new room
- pq.push(Reverse(end_time));
- pq.push(Reverse(intervals[i][1]));
- }
- }
+ let mut d: HashMap = HashMap::new();
+ for interval in intervals {
+ let (l, r) = (interval[0], interval[1]);
+ *d.entry(l).or_insert(0) += 1;
+ *d.entry(r).or_insert(0) -= 1;
+ }
+
+ let mut times: Vec = d.keys().cloned().collect();
+ times.sort();
+
+ let mut ans = 0;
+ let mut s = 0;
+ for time in times {
+ s += d[&time];
+ ans = ans.max(s);
}
- pq.len() as i32
+ ans
}
}
```
diff --git a/solution/0200-0299/0253.Meeting Rooms II/Solution.cpp b/solution/0200-0299/0253.Meeting Rooms II/Solution.cpp
index 2971b1431905a..0242f8d5e1651 100644
--- a/solution/0200-0299/0253.Meeting Rooms II/Solution.cpp
+++ b/solution/0200-0299/0253.Meeting Rooms II/Solution.cpp
@@ -1,15 +1,20 @@
class Solution {
public:
int minMeetingRooms(vector>& intervals) {
- int n = 1000010;
- vector delta(n);
- for (auto e : intervals) {
- ++delta[e[0]];
- --delta[e[1]];
+ int m = 0;
+ for (const auto& e : intervals) {
+ m = max(m, e[1]);
}
- for (int i = 0; i < n - 1; ++i) {
- delta[i + 1] += delta[i];
+ vector d(m + 1);
+ for (const auto& e : intervals) {
+ d[e[0]]++;
+ d[e[1]]--;
}
- return *max_element(delta.begin(), delta.end());
+ int ans = 0, s = 0;
+ for (int v : d) {
+ s += v;
+ ans = max(ans, s);
+ }
+ return ans;
}
-};
\ No newline at end of file
+};
diff --git a/solution/0200-0299/0253.Meeting Rooms II/Solution.go b/solution/0200-0299/0253.Meeting Rooms II/Solution.go
index 88f25a7a1410a..61bd1ca79a537 100644
--- a/solution/0200-0299/0253.Meeting Rooms II/Solution.go
+++ b/solution/0200-0299/0253.Meeting Rooms II/Solution.go
@@ -1,12 +1,19 @@
-func minMeetingRooms(intervals [][]int) int {
- n := 1000010
- delta := make([]int, n)
+func minMeetingRooms(intervals [][]int) (ans int) {
+ m := 0
for _, e := range intervals {
- delta[e[0]]++
- delta[e[1]]--
+ m = max(m, e[1])
}
- for i := 1; i < n; i++ {
- delta[i] += delta[i-1]
+
+ d := make([]int, m+1)
+ for _, e := range intervals {
+ d[e[0]]++
+ d[e[1]]--
+ }
+
+ s := 0
+ for _, v := range d {
+ s += v
+ ans = max(ans, s)
}
- return slices.Max(delta)
-}
\ No newline at end of file
+ return
+}
diff --git a/solution/0200-0299/0253.Meeting Rooms II/Solution.java b/solution/0200-0299/0253.Meeting Rooms II/Solution.java
index 42db9201e47d7..bfdb5285ced20 100644
--- a/solution/0200-0299/0253.Meeting Rooms II/Solution.java
+++ b/solution/0200-0299/0253.Meeting Rooms II/Solution.java
@@ -1,16 +1,19 @@
class Solution {
public int minMeetingRooms(int[][] intervals) {
- int n = 1000010;
- int[] delta = new int[n];
- for (int[] e : intervals) {
- ++delta[e[0]];
- --delta[e[1]];
+ int m = 0;
+ for (var e : intervals) {
+ m = Math.max(m, e[1]);
}
- int res = delta[0];
- for (int i = 1; i < n; ++i) {
- delta[i] += delta[i - 1];
- res = Math.max(res, delta[i]);
+ int[] d = new int[m + 1];
+ for (var e : intervals) {
+ ++d[e[0]];
+ --d[e[1]];
}
- return res;
+ int ans = 0, s = 0;
+ for (int v : d) {
+ s += v;
+ ans = Math.max(ans, s);
+ }
+ return ans;
}
-}
\ No newline at end of file
+}
diff --git a/solution/0200-0299/0253.Meeting Rooms II/Solution.py b/solution/0200-0299/0253.Meeting Rooms II/Solution.py
index 787a096dd3852..63ed57b18f5f4 100644
--- a/solution/0200-0299/0253.Meeting Rooms II/Solution.py
+++ b/solution/0200-0299/0253.Meeting Rooms II/Solution.py
@@ -1,7 +1,12 @@
class Solution:
def minMeetingRooms(self, intervals: List[List[int]]) -> int:
- delta = [0] * 1000010
- for start, end in intervals:
- delta[start] += 1
- delta[end] -= 1
- return max(accumulate(delta))
+ m = max(e[1] for e in intervals)
+ d = [0] * (m + 1)
+ for l, r in intervals:
+ d[l] += 1
+ d[r] -= 1
+ ans = s = 0
+ for v in d:
+ s += v
+ ans = max(ans, s)
+ return ans
diff --git a/solution/0200-0299/0253.Meeting Rooms II/Solution.rs b/solution/0200-0299/0253.Meeting Rooms II/Solution.rs
index ad9cd0a9b24ec..a11e467a2ada7 100644
--- a/solution/0200-0299/0253.Meeting Rooms II/Solution.rs
+++ b/solution/0200-0299/0253.Meeting Rooms II/Solution.rs
@@ -1,35 +1,23 @@
-use std::{cmp::Reverse, collections::BinaryHeap};
-
impl Solution {
- #[allow(dead_code)]
pub fn min_meeting_rooms(intervals: Vec>) -> i32 {
- // The min heap that stores the earliest ending time among all meeting rooms
- let mut pq = BinaryHeap::new();
- let mut intervals = intervals;
- let n = intervals.len();
-
- // Let's first sort the intervals vector
- intervals.sort_by(|lhs, rhs| lhs[0].cmp(&rhs[0]));
+ let mut m = 0;
+ for e in &intervals {
+ m = m.max(e[1]);
+ }
- // Push the first end time to the heap
- pq.push(Reverse(intervals[0][1]));
+ let mut d = vec![0; (m + 1) as usize];
+ for e in intervals {
+ d[e[0] as usize] += 1;
+ d[e[1] as usize] -= 1;
+ }
- // Traverse the intervals vector
- for i in 1..n {
- // Get the current top element from the heap
- if let Some(Reverse(end_time)) = pq.pop() {
- if end_time <= intervals[i][0] {
- // If the end time is early than the current begin time
- let new_end_time = intervals[i][1];
- pq.push(Reverse(new_end_time));
- } else {
- // Otherwise, push the end time back and we also need a new room
- pq.push(Reverse(end_time));
- pq.push(Reverse(intervals[i][1]));
- }
- }
+ let mut ans = 0;
+ let mut s = 0;
+ for v in d {
+ s += v;
+ ans = ans.max(s);
}
- pq.len() as i32
+ ans
}
}
diff --git a/solution/0200-0299/0253.Meeting Rooms II/Solution.ts b/solution/0200-0299/0253.Meeting Rooms II/Solution.ts
new file mode 100644
index 0000000000000..5a9811e8693c4
--- /dev/null
+++ b/solution/0200-0299/0253.Meeting Rooms II/Solution.ts
@@ -0,0 +1,14 @@
+function minMeetingRooms(intervals: number[][]): number {
+ const m = Math.max(...intervals.map(([_, r]) => r));
+ const d: number[] = Array(m + 1).fill(0);
+ for (const [l, r] of intervals) {
+ d[l]++;
+ d[r]--;
+ }
+ let [ans, s] = [0, 0];
+ for (const v of d) {
+ s += v;
+ ans = Math.max(ans, s);
+ }
+ return ans;
+}
diff --git a/solution/0200-0299/0253.Meeting Rooms II/Solution2.cpp b/solution/0200-0299/0253.Meeting Rooms II/Solution2.cpp
new file mode 100644
index 0000000000000..b7b455ebaf024
--- /dev/null
+++ b/solution/0200-0299/0253.Meeting Rooms II/Solution2.cpp
@@ -0,0 +1,16 @@
+class Solution {
+public:
+ int minMeetingRooms(vector>& intervals) {
+ map d;
+ for (const auto& e : intervals) {
+ d[e[0]]++;
+ d[e[1]]--;
+ }
+ int ans = 0, s = 0;
+ for (auto& [_, v] : d) {
+ s += v;
+ ans = max(ans, s);
+ }
+ return ans;
+ }
+};
diff --git a/solution/0200-0299/0253.Meeting Rooms II/Solution2.go b/solution/0200-0299/0253.Meeting Rooms II/Solution2.go
new file mode 100644
index 0000000000000..55278187da34e
--- /dev/null
+++ b/solution/0200-0299/0253.Meeting Rooms II/Solution2.go
@@ -0,0 +1,20 @@
+func minMeetingRooms(intervals [][]int) (ans int) {
+ d := make(map[int]int)
+ for _, e := range intervals {
+ d[e[0]]++
+ d[e[1]]--
+ }
+
+ keys := make([]int, 0, len(d))
+ for k := range d {
+ keys = append(keys, k)
+ }
+ sort.Ints(keys)
+
+ s := 0
+ for _, k := range keys {
+ s += d[k]
+ ans = max(ans, s)
+ }
+ return
+}
diff --git a/solution/0200-0299/0253.Meeting Rooms II/Solution2.java b/solution/0200-0299/0253.Meeting Rooms II/Solution2.java
new file mode 100644
index 0000000000000..64b95cef08d44
--- /dev/null
+++ b/solution/0200-0299/0253.Meeting Rooms II/Solution2.java
@@ -0,0 +1,15 @@
+class Solution {
+ public int minMeetingRooms(int[][] intervals) {
+ Map d = new TreeMap<>();
+ for (var e : intervals) {
+ d.merge(e[0], 1, Integer::sum);
+ d.merge(e[1], -1, Integer::sum);
+ }
+ int ans = 0, s = 0;
+ for (var e : d.values()) {
+ s += e;
+ ans = Math.max(ans, s);
+ }
+ return ans;
+ }
+}
diff --git a/solution/0200-0299/0253.Meeting Rooms II/Solution2.py b/solution/0200-0299/0253.Meeting Rooms II/Solution2.py
new file mode 100644
index 0000000000000..0db564338d7ff
--- /dev/null
+++ b/solution/0200-0299/0253.Meeting Rooms II/Solution2.py
@@ -0,0 +1,11 @@
+class Solution:
+ def minMeetingRooms(self, intervals: List[List[int]]) -> int:
+ d = defaultdict(int)
+ for l, r in intervals:
+ d[l] += 1
+ d[r] -= 1
+ ans = s = 0
+ for _, v in sorted(d.items()):
+ s += v
+ ans = max(ans, s)
+ return ans
diff --git a/solution/0200-0299/0253.Meeting Rooms II/Solution2.rs b/solution/0200-0299/0253.Meeting Rooms II/Solution2.rs
new file mode 100644
index 0000000000000..e35197162e2e3
--- /dev/null
+++ b/solution/0200-0299/0253.Meeting Rooms II/Solution2.rs
@@ -0,0 +1,24 @@
+use std::collections::HashMap;
+
+impl Solution {
+ pub fn min_meeting_rooms(intervals: Vec>) -> i32 {
+ let mut d: HashMap = HashMap::new();
+ for interval in intervals {
+ let (l, r) = (interval[0], interval[1]);
+ *d.entry(l).or_insert(0) += 1;
+ *d.entry(r).or_insert(0) -= 1;
+ }
+
+ let mut times: Vec = d.keys().cloned().collect();
+ times.sort();
+
+ let mut ans = 0;
+ let mut s = 0;
+ for time in times {
+ s += d[&time];
+ ans = ans.max(s);
+ }
+
+ ans
+ }
+}
diff --git a/solution/0200-0299/0253.Meeting Rooms II/Solution2.ts b/solution/0200-0299/0253.Meeting Rooms II/Solution2.ts
new file mode 100644
index 0000000000000..90a204cead1cc
--- /dev/null
+++ b/solution/0200-0299/0253.Meeting Rooms II/Solution2.ts
@@ -0,0 +1,17 @@
+function minMeetingRooms(intervals: number[][]): number {
+ const d: { [key: number]: number } = {};
+ for (const [l, r] of intervals) {
+ d[l] = (d[l] || 0) + 1;
+ d[r] = (d[r] || 0) - 1;
+ }
+
+ let [ans, s] = [0, 0];
+ const keys = Object.keys(d)
+ .map(Number)
+ .sort((a, b) => a - b);
+ for (const k of keys) {
+ s += d[k];
+ ans = Math.max(ans, s);
+ }
+ return ans;
+}
diff --git a/solution/0200-0299/0262.Trips and Users/README.md b/solution/0200-0299/0262.Trips and Users/README.md
index 46938213c4cc8..87e992577500e 100644
--- a/solution/0200-0299/0262.Trips and Users/README.md
+++ b/solution/0200-0299/0262.Trips and Users/README.md
@@ -36,8 +36,6 @@ id 是这张表的主键(具有唯一值的列)。
status 是一个表示行程状态的枚举类型,枚举成员为(‘completed’, ‘cancelled_by_driver’, ‘cancelled_by_client’) 。
-
diff --git a/solution/0200-0299/0262.Trips and Users/README_EN.md b/solution/0200-0299/0262.Trips and Users/README_EN.md
index bc65cecf1beeb..57a1ddaa591f8 100644
--- a/solution/0200-0299/0262.Trips and Users/README_EN.md
+++ b/solution/0200-0299/0262.Trips and Users/README_EN.md
@@ -34,7 +34,7 @@ The table holds all taxi trips. Each trip has a unique id, while client_id and d
Status is an ENUM (category) type of ('completed', 'cancelled_by_driver', 'cancelled_by_client').
-
+
Table: Users
@@ -51,7 +51,7 @@ The table holds all users. Each user has a unique users_id, and role is an ENUM
banned is an ENUM (category) type of ('Yes', 'No').
-
+
The cancellation rate is computed by dividing the number of canceled (by client or driver) requests with unbanned users by the total number of requests with unbanned users on that day.
@@ -59,7 +59,7 @@ banned is an ENUM (category) type of ('Yes', 'No').
Return the result table in any order.
-
The result format is in the following example.
+
The result format is in the following example.
Example 1:
diff --git a/solution/0200-0299/0269.Alien Dictionary/README.md b/solution/0200-0299/0269.Alien Dictionary/README.md
index b1185f65b06a0..308a96369b8e8 100644
--- a/solution/0200-0299/0269.Alien Dictionary/README.md
+++ b/solution/0200-0299/0269.Alien Dictionary/README.md
@@ -288,6 +288,87 @@ public:
};
```
+#### Go
+
+```go
+func alienOrder(words []string) string {
+ g := [26][26]bool{}
+ s := [26]bool{}
+ cnt := 0
+ n := len(words)
+ for i := 0; i < n-1; i++ {
+ for _, c := range words[i] {
+ if cnt == 26 {
+ break
+ }
+ c -= 'a'
+ if !s[c] {
+ cnt++
+ s[c] = true
+ }
+ }
+ m := len(words[i])
+ for j := 0; j < m; j++ {
+ if j >= len(words[i+1]) {
+ return ""
+ }
+ c1, c2 := words[i][j]-'a', words[i+1][j]-'a'
+ if c1 == c2 {
+ continue
+ }
+ if g[c2][c1] {
+ return ""
+ }
+ g[c1][c2] = true
+ break
+ }
+ }
+ for _, c := range words[n-1] {
+ if cnt == 26 {
+ break
+ }
+ c -= 'a'
+ if !s[c] {
+ cnt++
+ s[c] = true
+ }
+ }
+
+ inDegree := [26]int{}
+ for _, out := range g {
+ for i, v := range out {
+ if v {
+ inDegree[i]++
+ }
+ }
+ }
+ q := []int{}
+ for i, in := range inDegree {
+ if in == 0 && s[i] {
+ q = append(q, i)
+ }
+ }
+ ans := ""
+ for len(q) > 0 {
+ t := q[0]
+ q = q[1:]
+ ans += string(t + 'a')
+ for i, v := range g[t] {
+ if v {
+ inDegree[i]--
+ if inDegree[i] == 0 && s[i] {
+ q = append(q, i)
+ }
+ }
+ }
+ }
+ if len(ans) < cnt {
+ return ""
+ }
+ return ans
+}
+```
+
diff --git a/solution/0200-0299/0269.Alien Dictionary/README_EN.md b/solution/0200-0299/0269.Alien Dictionary/README_EN.md
index 9677cf9f30970..24d8925dfb9a6 100644
--- a/solution/0200-0299/0269.Alien Dictionary/README_EN.md
+++ b/solution/0200-0299/0269.Alien Dictionary/README_EN.md
@@ -269,6 +269,87 @@ public:
};
```
+#### Go
+
+```go
+func alienOrder(words []string) string {
+ g := [26][26]bool{}
+ s := [26]bool{}
+ cnt := 0
+ n := len(words)
+ for i := 0; i < n-1; i++ {
+ for _, c := range words[i] {
+ if cnt == 26 {
+ break
+ }
+ c -= 'a'
+ if !s[c] {
+ cnt++
+ s[c] = true
+ }
+ }
+ m := len(words[i])
+ for j := 0; j < m; j++ {
+ if j >= len(words[i+1]) {
+ return ""
+ }
+ c1, c2 := words[i][j]-'a', words[i+1][j]-'a'
+ if c1 == c2 {
+ continue
+ }
+ if g[c2][c1] {
+ return ""
+ }
+ g[c1][c2] = true
+ break
+ }
+ }
+ for _, c := range words[n-1] {
+ if cnt == 26 {
+ break
+ }
+ c -= 'a'
+ if !s[c] {
+ cnt++
+ s[c] = true
+ }
+ }
+
+ inDegree := [26]int{}
+ for _, out := range g {
+ for i, v := range out {
+ if v {
+ inDegree[i]++
+ }
+ }
+ }
+ q := []int{}
+ for i, in := range inDegree {
+ if in == 0 && s[i] {
+ q = append(q, i)
+ }
+ }
+ ans := ""
+ for len(q) > 0 {
+ t := q[0]
+ q = q[1:]
+ ans += string(t + 'a')
+ for i, v := range g[t] {
+ if v {
+ inDegree[i]--
+ if inDegree[i] == 0 && s[i] {
+ q = append(q, i)
+ }
+ }
+ }
+ }
+ if len(ans) < cnt {
+ return ""
+ }
+ return ans
+}
+```
+
diff --git a/solution/0200-0299/0269.Alien Dictionary/Solution.go b/solution/0200-0299/0269.Alien Dictionary/Solution.go
new file mode 100644
index 0000000000000..b49abee4bad20
--- /dev/null
+++ b/solution/0200-0299/0269.Alien Dictionary/Solution.go
@@ -0,0 +1,76 @@
+func alienOrder(words []string) string {
+ g := [26][26]bool{}
+ s := [26]bool{}
+ cnt := 0
+ n := len(words)
+ for i := 0; i < n-1; i++ {
+ for _, c := range words[i] {
+ if cnt == 26 {
+ break
+ }
+ c -= 'a'
+ if !s[c] {
+ cnt++
+ s[c] = true
+ }
+ }
+ m := len(words[i])
+ for j := 0; j < m; j++ {
+ if j >= len(words[i+1]) {
+ return ""
+ }
+ c1, c2 := words[i][j]-'a', words[i+1][j]-'a'
+ if c1 == c2 {
+ continue
+ }
+ if g[c2][c1] {
+ return ""
+ }
+ g[c1][c2] = true
+ break
+ }
+ }
+ for _, c := range words[n-1] {
+ if cnt == 26 {
+ break
+ }
+ c -= 'a'
+ if !s[c] {
+ cnt++
+ s[c] = true
+ }
+ }
+
+ inDegree := [26]int{}
+ for _, out := range g {
+ for i, v := range out {
+ if v {
+ inDegree[i]++
+ }
+ }
+ }
+ q := []int{}
+ for i, in := range inDegree {
+ if in == 0 && s[i] {
+ q = append(q, i)
+ }
+ }
+ ans := ""
+ for len(q) > 0 {
+ t := q[0]
+ q = q[1:]
+ ans += string(t + 'a')
+ for i, v := range g[t] {
+ if v {
+ inDegree[i]--
+ if inDegree[i] == 0 && s[i] {
+ q = append(q, i)
+ }
+ }
+ }
+ }
+ if len(ans) < cnt {
+ return ""
+ }
+ return ans
+}
diff --git a/solution/0200-0299/0275.H-Index II/README.md b/solution/0200-0299/0275.H-Index II/README.md
index 546a3242358e5..47b3a5e04dfb9 100644
--- a/solution/0200-0299/0275.H-Index II/README.md
+++ b/solution/0200-0299/0275.H-Index II/README.md
@@ -17,7 +17,7 @@ tags:
-
Given an array of integers citations where citations[i] is the number of citations a researcher received for their ith paper and citations is sorted in ascending order, return the researcher's h-index.
+
Given an array of integers citations where citations[i] is the number of citations a researcher received for their ith paper and citations is sorted in non-descending order, return the researcher's h-index.
According to the definition of h-index on Wikipedia: The h-index is defined as the maximum value of h such that the given researcher has published at least h papers that have each been cited at least h times.
diff --git a/solution/0200-0299/0281.Zigzag Iterator/README.md b/solution/0200-0299/0281.Zigzag Iterator/README.md
index 58c0422f2a7ad..63babb7957b71 100644
--- a/solution/0200-0299/0281.Zigzag Iterator/README.md
+++ b/solution/0200-0299/0281.Zigzag Iterator/README.md
@@ -149,6 +149,54 @@ public class ZigzagIterator {
*/
```
+#### Go
+
+```go
+type ZigzagIterator struct {
+ cur int
+ size int
+ indexes []int
+ vectors [][]int
+}
+
+func Constructor(v1, v2 []int) *ZigzagIterator {
+ return &ZigzagIterator{
+ cur: 0,
+ size: 2,
+ indexes: []int{0, 0},
+ vectors: [][]int{v1, v2},
+ }
+}
+
+func (this *ZigzagIterator) next() int {
+ vector := this.vectors[this.cur]
+ index := this.indexes[this.cur]
+ res := vector[index]
+ this.indexes[this.cur]++
+ this.cur = (this.cur + 1) % this.size
+ return res
+}
+
+func (this *ZigzagIterator) hasNext() bool {
+ start := this.cur
+ for this.indexes[this.cur] == len(this.vectors[this.cur]) {
+ this.cur = (this.cur + 1) % this.size
+ if start == this.cur {
+ return false
+ }
+ }
+ return true
+}
+
+/**
+ * Your ZigzagIterator object will be instantiated and called as such:
+ * obj := Constructor(param_1, param_2);
+ * for obj.hasNext() {
+ * ans = append(ans, obj.next())
+ * }
+ */
+```
+
#### Rust
```rust
diff --git a/solution/0200-0299/0281.Zigzag Iterator/README_EN.md b/solution/0200-0299/0281.Zigzag Iterator/README_EN.md
index 577e8df1e3bd6..46a607542a76e 100644
--- a/solution/0200-0299/0281.Zigzag Iterator/README_EN.md
+++ b/solution/0200-0299/0281.Zigzag Iterator/README_EN.md
@@ -163,6 +163,54 @@ public class ZigzagIterator {
*/
```
+#### Go
+
+```go
+type ZigzagIterator struct {
+ cur int
+ size int
+ indexes []int
+ vectors [][]int
+}
+
+func Constructor(v1, v2 []int) *ZigzagIterator {
+ return &ZigzagIterator{
+ cur: 0,
+ size: 2,
+ indexes: []int{0, 0},
+ vectors: [][]int{v1, v2},
+ }
+}
+
+func (this *ZigzagIterator) next() int {
+ vector := this.vectors[this.cur]
+ index := this.indexes[this.cur]
+ res := vector[index]
+ this.indexes[this.cur]++
+ this.cur = (this.cur + 1) % this.size
+ return res
+}
+
+func (this *ZigzagIterator) hasNext() bool {
+ start := this.cur
+ for this.indexes[this.cur] == len(this.vectors[this.cur]) {
+ this.cur = (this.cur + 1) % this.size
+ if start == this.cur {
+ return false
+ }
+ }
+ return true
+}
+
+/**
+ * Your ZigzagIterator object will be instantiated and called as such:
+ * obj := Constructor(param_1, param_2);
+ * for obj.hasNext() {
+ * ans = append(ans, obj.next())
+ * }
+ */
+```
+
#### Rust
```rust
diff --git a/solution/0200-0299/0281.Zigzag Iterator/Solution.go b/solution/0200-0299/0281.Zigzag Iterator/Solution.go
new file mode 100644
index 0000000000000..814dd960d3a17
--- /dev/null
+++ b/solution/0200-0299/0281.Zigzag Iterator/Solution.go
@@ -0,0 +1,43 @@
+type ZigzagIterator struct {
+ cur int
+ size int
+ indexes []int
+ vectors [][]int
+}
+
+func Constructor(v1, v2 []int) *ZigzagIterator {
+ return &ZigzagIterator{
+ cur: 0,
+ size: 2,
+ indexes: []int{0, 0},
+ vectors: [][]int{v1, v2},
+ }
+}
+
+func (this *ZigzagIterator) next() int {
+ vector := this.vectors[this.cur]
+ index := this.indexes[this.cur]
+ res := vector[index]
+ this.indexes[this.cur]++
+ this.cur = (this.cur + 1) % this.size
+ return res
+}
+
+func (this *ZigzagIterator) hasNext() bool {
+ start := this.cur
+ for this.indexes[this.cur] == len(this.vectors[this.cur]) {
+ this.cur = (this.cur + 1) % this.size
+ if start == this.cur {
+ return false
+ }
+ }
+ return true
+}
+
+/**
+ * Your ZigzagIterator object will be instantiated and called as such:
+ * obj := Constructor(param_1, param_2);
+ * for obj.hasNext() {
+ * ans = append(ans, obj.next())
+ * }
+ */
diff --git a/solution/0200-0299/0282.Expression Add Operators/README.md b/solution/0200-0299/0282.Expression Add Operators/README.md
index 7c63777b267a2..c5664ca7786b9 100644
--- a/solution/0200-0299/0282.Expression Add Operators/README.md
+++ b/solution/0200-0299/0282.Expression Add Operators/README.md
@@ -18,10 +18,12 @@ tags:
-
给定一个仅包含数字 0-9 的字符串 num 和一个目标值整数 target ,在 num 的数字之间添加 二元 运算符(不是一元)+、- 或 * ,返回 所有 能够得到 target 的表达式。
+
给定一个仅包含数字 0-9 的字符串 num 和一个目标值整数 target ,在 num 的数字之间添加 二元 运算符(不是一元)+、- 或 * ,返回 所有 能够得到 target 的表达式。
Note that operands in the returned expressions should not contain leading zeros.
+
Note that a number can contain multiple digits.
+
Example 1:
diff --git a/solution/0300-0399/0307.Range Sum Query - Mutable/README.md b/solution/0300-0399/0307.Range Sum Query - Mutable/README.md
index 73f33a3388a62..03d184f9857ae 100644
--- a/solution/0300-0399/0307.Range Sum Query - Mutable/README.md
+++ b/solution/0300-0399/0307.Range Sum Query - Mutable/README.md
@@ -7,6 +7,7 @@ tags:
- 树状数组
- 线段树
- 数组
+ - 分治
---
diff --git a/solution/0300-0399/0307.Range Sum Query - Mutable/README_EN.md b/solution/0300-0399/0307.Range Sum Query - Mutable/README_EN.md
index 380df451ebaaf..b9a6a0b062f3b 100644
--- a/solution/0300-0399/0307.Range Sum Query - Mutable/README_EN.md
+++ b/solution/0300-0399/0307.Range Sum Query - Mutable/README_EN.md
@@ -7,6 +7,7 @@ tags:
- Binary Indexed Tree
- Segment Tree
- Array
+ - Divide and Conquer
---
diff --git a/solution/0300-0399/0308.Range Sum Query 2D - Mutable/README.md b/solution/0300-0399/0308.Range Sum Query 2D - Mutable/README.md
index 7beaa49386445..ce09eb5f47c0d 100644
--- a/solution/0300-0399/0308.Range Sum Query 2D - Mutable/README.md
+++ b/solution/0300-0399/0308.Range Sum Query 2D - Mutable/README.md
@@ -62,13 +62,13 @@ numMatrix.sumRegion(2, 1, 4, 3); // 返回 10 (即,右侧红色矩形的和)
m == matrix.length
n == matrix[i].length
1 <= m, n <= 200
-
-105 <= matrix[i][j] <= 105
+
-1000 <= matrix[i][j] <= 1000
0 <= row < m
0 <= col < n
-
-105 <= val <= 105
+
-1000 <= val <= 1000
0 <= row1 <= row2 < m
0 <= col1 <= col2 < n
-
最多调用104 次 sumRegion 和 update 方法
+
最多调用5000 次 sumRegion 和 update 方法
diff --git a/solution/0300-0399/0317.Shortest Distance from All Buildings/README.md b/solution/0300-0399/0317.Shortest Distance from All Buildings/README.md
index a41c44f4a91dc..b533ce8d0056f 100644
--- a/solution/0300-0399/0317.Shortest Distance from All Buildings/README.md
+++ b/solution/0300-0399/0317.Shortest Distance from All Buildings/README.md
@@ -32,8 +32,6 @@ tags:
diff --git a/solution/0300-0399/0317.Shortest Distance from All Buildings/README_EN.md b/solution/0300-0399/0317.Shortest Distance from All Buildings/README_EN.md
index 816bbabef6c3d..edd540c52e03d 100644
--- a/solution/0300-0399/0317.Shortest Distance from All Buildings/README_EN.md
+++ b/solution/0300-0399/0317.Shortest Distance from All Buildings/README_EN.md
@@ -32,8 +32,6 @@ tags:
The total travel distance is the sum of the distances between the houses of the friends and the meeting point.
-
The distance is calculated using Manhattan Distance, where distance(p1, p2) = |p2.x - p1.x| + |p2.y - p1.y|.
-
Example 1:
diff --git a/solution/0300-0399/0325.Maximum Size Subarray Sum Equals k/README.md b/solution/0300-0399/0325.Maximum Size Subarray Sum Equals k/README.md
index 128bebe51d7b5..46ff907c57ab8 100644
--- a/solution/0300-0399/0325.Maximum Size Subarray Sum Equals k/README.md
+++ b/solution/0300-0399/0325.Maximum Size Subarray Sum Equals k/README.md
@@ -55,13 +55,13 @@ tags:
### 方法一:哈希表 + 前缀和
-我们可以用一个哈希表 $d$ 记录数组 $nums$ 中每个前缀和第一次出现的下标,初始时 $d[0] = -1$。另外定义一个变量 $s$ 记录前缀和。
+我们可以用一个哈希表 $\textit{d}$ 记录数组 $\textit{nums}$ 中每个前缀和第一次出现的下标,初始时 $\textit{d}[0] = -1$。另外定义一个变量 $\textit{s}$ 记录前缀和。
-接下来,遍历数组 $nums$,对于当前遍历到的数字 $nums[i]$,我们更新前缀和 $s = s + nums[i]$,如果 $s-k$ 在哈希表 $d$ 中存在,不妨记 $j = d[s - k]$,那么以 $nums[i]$ 结尾的符合条件的子数组的长度为 $i - j$,我们使用一个变量 $ans$ 来维护最长的符合条件的子数组的长度。然后,如果 $s$ 在哈希表中不存在,我们记录 $s$ 和对应的下标 $i$,即 $d[s] = i$,否则我们不更新 $d[s]$。需要注意的是,可能会有多个位置 $i$ 都满足 $s$ 的值,因此我们只记录最小的 $i$,这样就能保证子数组的长度最长。
+接下来,遍历数组 $\textit{nums}$,对于当前遍历到的数字 $\textit{nums}[i]$,我们更新前缀和 $\textit{s} = \textit{s} + \textit{nums}[i]$,如果 $\textit{s}-k$ 在哈希表 $\textit{d}$ 中存在,不妨记 $j = \textit{d}[\textit{s} - k]$,那么以 $\textit{nums}[i]$ 结尾的符合条件的子数组的长度为 $i - j$,我们使用一个变量 $\textit{ans}$ 来维护最长的符合条件的子数组的长度。然后,如果 $\textit{s}$ 在哈希表中不存在,我们记录 $\textit{s}$ 和对应的下标 $i$,即 $\textit{d}[\textit{s}] = i$,否则我们不更新 $\textit{d}[\textit{s}]$。需要注意的是,可能会有多个位置 $i$ 都满足 $\textit{s}$ 的值,因此我们只记录最小的 $i$,这样就能保证子数组的长度最长。
-遍历结束之后,我们返回 $ans$ 即可。
+遍历结束之后,我们返回 $\textit{ans}$ 即可。
-时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $nums$ 的长度。
+时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $\textit{nums}$ 的长度。
@@ -163,6 +163,80 @@ function maxSubArrayLen(nums: number[], k: number): number {
}
```
+#### Rust
+
+```rust
+use std::collections::HashMap;
+
+impl Solution {
+ pub fn max_sub_array_len(nums: Vec, k: i32) -> i32 {
+ let mut d = HashMap::new();
+ d.insert(0, -1);
+ let mut ans = 0;
+ let mut s = 0;
+
+ for (i, &x) in nums.iter().enumerate() {
+ s += x;
+ if let Some(&j) = d.get(&(s - k)) {
+ ans = ans.max((i as i32) - j);
+ }
+ d.entry(s).or_insert(i as i32);
+ }
+
+ ans
+ }
+}
+```
+
+#### JavaScript
+
+```js
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number}
+ */
+var maxSubArrayLen = function (nums, k) {
+ const d = new Map();
+ d.set(0, -1);
+ let ans = 0;
+ let s = 0;
+ for (let i = 0; i < nums.length; ++i) {
+ s += nums[i];
+ if (d.has(s - k)) {
+ ans = Math.max(ans, i - d.get(s - k));
+ }
+ if (!d.has(s)) {
+ d.set(s, i);
+ }
+ }
+ return ans;
+};
+```
+
+#### C#
+
+```cs
+public class Solution {
+ public int MaxSubArrayLen(int[] nums, int k) {
+ var d = new Dictionary();
+ d[0] = -1;
+ int ans = 0;
+ int s = 0;
+ for (int i = 0; i < nums.Length; i++) {
+ s += nums[i];
+ if (d.ContainsKey(s - k)) {
+ ans = Math.Max(ans, i - d[s - k]);
+ }
+ if (!d.ContainsKey(s)) {
+ d[s] = i;
+ }
+ }
+ return ans;
+ }
+}
+```
+
diff --git a/solution/0300-0399/0325.Maximum Size Subarray Sum Equals k/README_EN.md b/solution/0300-0399/0325.Maximum Size Subarray Sum Equals k/README_EN.md
index faa73742e4b73..6c708b0a1b002 100644
--- a/solution/0300-0399/0325.Maximum Size Subarray Sum Equals k/README_EN.md
+++ b/solution/0300-0399/0325.Maximum Size Subarray Sum Equals k/README_EN.md
@@ -52,7 +52,15 @@ tags:
-### Solution 1
+### Solution 1: Hash Table + Prefix Sum
+
+We can use a hash table $\textit{d}$ to record the first occurrence index of each prefix sum in the array $\textit{nums}$, initializing $\textit{d}[0] = -1$. Additionally, we define a variable $\textit{s}$ to keep track of the current prefix sum.
+
+Next, we iterate through the array $\textit{nums}$. For the current number $\textit{nums}[i]$, we update the prefix sum $\textit{s} = \textit{s} + \textit{nums}[i]$. If $\textit{s} - k$ exists in the hash table $\textit{d}$, let $\textit{j} = \textit{d}[\textit{s} - k]$, then the length of the subarray that ends at $\textit{nums}[i]$ and satisfies the condition is $i - j$. We use a variable $\textit{ans}$ to maintain the length of the longest subarray that satisfies the condition. After that, if $\textit{s}$ does not exist in the hash table, we record $\textit{s}$ and its corresponding index $i$ by setting $\textit{d}[\textit{s}] = i$. Otherwise, we do not update $\textit{d}[\textit{s}]$. It is important to note that there may be multiple positions $i$ with the same value of $\textit{s}$, so we only record the smallest $i$ to ensure the subarray length is the longest.
+
+After the iteration ends, we return $\textit{ans}$.
+
+The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the array $\textit{nums}$.
@@ -154,6 +162,80 @@ function maxSubArrayLen(nums: number[], k: number): number {
}
```
+#### Rust
+
+```rust
+use std::collections::HashMap;
+
+impl Solution {
+ pub fn max_sub_array_len(nums: Vec, k: i32) -> i32 {
+ let mut d = HashMap::new();
+ d.insert(0, -1);
+ let mut ans = 0;
+ let mut s = 0;
+
+ for (i, &x) in nums.iter().enumerate() {
+ s += x;
+ if let Some(&j) = d.get(&(s - k)) {
+ ans = ans.max((i as i32) - j);
+ }
+ d.entry(s).or_insert(i as i32);
+ }
+
+ ans
+ }
+}
+```
+
+#### JavaScript
+
+```js
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number}
+ */
+var maxSubArrayLen = function (nums, k) {
+ const d = new Map();
+ d.set(0, -1);
+ let ans = 0;
+ let s = 0;
+ for (let i = 0; i < nums.length; ++i) {
+ s += nums[i];
+ if (d.has(s - k)) {
+ ans = Math.max(ans, i - d.get(s - k));
+ }
+ if (!d.has(s)) {
+ d.set(s, i);
+ }
+ }
+ return ans;
+};
+```
+
+#### C#
+
+```cs
+public class Solution {
+ public int MaxSubArrayLen(int[] nums, int k) {
+ var d = new Dictionary();
+ d[0] = -1;
+ int ans = 0;
+ int s = 0;
+ for (int i = 0; i < nums.Length; i++) {
+ s += nums[i];
+ if (d.ContainsKey(s - k)) {
+ ans = Math.Max(ans, i - d[s - k]);
+ }
+ if (!d.ContainsKey(s)) {
+ d[s] = i;
+ }
+ }
+ return ans;
+ }
+}
+```
+
diff --git a/solution/0300-0399/0325.Maximum Size Subarray Sum Equals k/Solution.cs b/solution/0300-0399/0325.Maximum Size Subarray Sum Equals k/Solution.cs
new file mode 100644
index 0000000000000..209eabe2162d3
--- /dev/null
+++ b/solution/0300-0399/0325.Maximum Size Subarray Sum Equals k/Solution.cs
@@ -0,0 +1,18 @@
+public class Solution {
+ public int MaxSubArrayLen(int[] nums, int k) {
+ var d = new Dictionary();
+ d[0] = -1;
+ int ans = 0;
+ int s = 0;
+ for (int i = 0; i < nums.Length; i++) {
+ s += nums[i];
+ if (d.ContainsKey(s - k)) {
+ ans = Math.Max(ans, i - d[s - k]);
+ }
+ if (!d.ContainsKey(s)) {
+ d[s] = i;
+ }
+ }
+ return ans;
+ }
+}
diff --git a/solution/0300-0399/0325.Maximum Size Subarray Sum Equals k/Solution.js b/solution/0300-0399/0325.Maximum Size Subarray Sum Equals k/Solution.js
new file mode 100644
index 0000000000000..dc542c5d2fa24
--- /dev/null
+++ b/solution/0300-0399/0325.Maximum Size Subarray Sum Equals k/Solution.js
@@ -0,0 +1,21 @@
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number}
+ */
+var maxSubArrayLen = function (nums, k) {
+ const d = new Map();
+ d.set(0, -1);
+ let ans = 0;
+ let s = 0;
+ for (let i = 0; i < nums.length; ++i) {
+ s += nums[i];
+ if (d.has(s - k)) {
+ ans = Math.max(ans, i - d.get(s - k));
+ }
+ if (!d.has(s)) {
+ d.set(s, i);
+ }
+ }
+ return ans;
+};
diff --git a/solution/0300-0399/0325.Maximum Size Subarray Sum Equals k/Solution.rs b/solution/0300-0399/0325.Maximum Size Subarray Sum Equals k/Solution.rs
new file mode 100644
index 0000000000000..e011cb1e1c458
--- /dev/null
+++ b/solution/0300-0399/0325.Maximum Size Subarray Sum Equals k/Solution.rs
@@ -0,0 +1,20 @@
+use std::collections::HashMap;
+
+impl Solution {
+ pub fn max_sub_array_len(nums: Vec, k: i32) -> i32 {
+ let mut d = HashMap::new();
+ d.insert(0, -1);
+ let mut ans = 0;
+ let mut s = 0;
+
+ for (i, &x) in nums.iter().enumerate() {
+ s += x;
+ if let Some(&j) = d.get(&(s - k)) {
+ ans = ans.max((i as i32) - j);
+ }
+ d.entry(s).or_insert(i as i32);
+ }
+
+ ans
+ }
+}
diff --git a/solution/0300-0399/0326.Power of Three/README.md b/solution/0300-0399/0326.Power of Three/README.md
index 22c533c88f604..2a2815575a6e0 100644
--- a/solution/0300-0399/0326.Power of Three/README.md
+++ b/solution/0300-0399/0326.Power of Three/README.md
@@ -140,7 +140,29 @@ func isPowerOfThree(n int) bool {
```ts
function isPowerOfThree(n: number): boolean {
- return n > 0 && 1162261467 % n == 0;
+ while (n > 2) {
+ if (n % 3 !== 0) {
+ return false;
+ }
+ n = Math.floor(n / 3);
+ }
+ return n === 1;
+}
+```
+
+#### Rust
+
+```rust
+impl Solution {
+ pub fn is_power_of_three(mut n: i32) -> bool {
+ while n > 2 {
+ if n % 3 != 0 {
+ return false;
+ }
+ n /= 3;
+ }
+ n == 1
+ }
}
```
@@ -152,7 +174,13 @@ function isPowerOfThree(n: number): boolean {
* @return {boolean}
*/
var isPowerOfThree = function (n) {
- return n > 0 && 1162261467 % n == 0;
+ while (n > 2) {
+ if (n % 3 !== 0) {
+ return false;
+ }
+ n = Math.floor(n / 3);
+ }
+ return n === 1;
};
```
@@ -207,6 +235,36 @@ func isPowerOfThree(n int) bool {
}
```
+#### TypeScript
+
+```ts
+function isPowerOfThree(n: number): boolean {
+ return n > 0 && 1162261467 % n == 0;
+}
+```
+
+#### Rust
+
+```rust
+impl Solution {
+ pub fn is_power_of_three(mut n: i32) -> bool {
+ n > 0 && 1162261467 % n == 0
+ }
+}
+```
+
+#### JavaScript
+
+```js
+/**
+ * @param {number} n
+ * @return {boolean}
+ */
+var isPowerOfThree = function (n) {
+ return n > 0 && 1162261467 % n == 0;
+};
+```
+
diff --git a/solution/0300-0399/0326.Power of Three/README_EN.md b/solution/0300-0399/0326.Power of Three/README_EN.md
index 094641c44352c..5b51ad90ca7a4 100644
--- a/solution/0300-0399/0326.Power of Three/README_EN.md
+++ b/solution/0300-0399/0326.Power of Three/README_EN.md
@@ -62,7 +62,11 @@ tags:
-### Solution 1
+### Solution 1: Trial Division
+
+If $n \gt 2$, we can continuously divide $n$ by $3$. If it's not divisible, it means $n$ is not a power of $3$, otherwise we continue dividing by $3$ until $n$ is less than or equal to $2$. If $n$ equals $1$, it means $n$ is a power of $3$, otherwise it's not a power of $3$.
+
+Time complexity $O(\log_3n)$, space complexity $O(1)$.
@@ -129,7 +133,29 @@ func isPowerOfThree(n int) bool {
```ts
function isPowerOfThree(n: number): boolean {
- return n > 0 && 1162261467 % n == 0;
+ while (n > 2) {
+ if (n % 3 !== 0) {
+ return false;
+ }
+ n = Math.floor(n / 3);
+ }
+ return n === 1;
+}
+```
+
+#### Rust
+
+```rust
+impl Solution {
+ pub fn is_power_of_three(mut n: i32) -> bool {
+ while n > 2 {
+ if n % 3 != 0 {
+ return false;
+ }
+ n /= 3;
+ }
+ n == 1
+ }
}
```
@@ -141,7 +167,13 @@ function isPowerOfThree(n: number): boolean {
* @return {boolean}
*/
var isPowerOfThree = function (n) {
- return n > 0 && 1162261467 % n == 0;
+ while (n > 2) {
+ if (n % 3 !== 0) {
+ return false;
+ }
+ n = Math.floor(n / 3);
+ }
+ return n === 1;
};
```
@@ -151,7 +183,11 @@ var isPowerOfThree = function (n) {
-### Solution 2
+### Solution 2: Mathematics
+
+If $n$ is a power of $3$, then the maximum value of $n$ is $3^{19} = 1162261467$. Therefore, we only need to check if $n$ is a divisor of $3^{19}$.
+
+Time complexity $O(1)$, space complexity $O(1)$.
@@ -192,6 +228,36 @@ func isPowerOfThree(n int) bool {
}
```
+#### TypeScript
+
+```ts
+function isPowerOfThree(n: number): boolean {
+ return n > 0 && 1162261467 % n == 0;
+}
+```
+
+#### Rust
+
+```rust
+impl Solution {
+ pub fn is_power_of_three(mut n: i32) -> bool {
+ n > 0 && 1162261467 % n == 0
+ }
+}
+```
+
+#### JavaScript
+
+```js
+/**
+ * @param {number} n
+ * @return {boolean}
+ */
+var isPowerOfThree = function (n) {
+ return n > 0 && 1162261467 % n == 0;
+};
+```
+
diff --git a/solution/0300-0399/0326.Power of Three/Solution.js b/solution/0300-0399/0326.Power of Three/Solution.js
index 7b9ee58149669..384ebce324d33 100644
--- a/solution/0300-0399/0326.Power of Three/Solution.js
+++ b/solution/0300-0399/0326.Power of Three/Solution.js
@@ -3,5 +3,11 @@
* @return {boolean}
*/
var isPowerOfThree = function (n) {
- return n > 0 && 1162261467 % n == 0;
+ while (n > 2) {
+ if (n % 3 !== 0) {
+ return false;
+ }
+ n = Math.floor(n / 3);
+ }
+ return n === 1;
};
diff --git a/solution/0300-0399/0326.Power of Three/Solution.rs b/solution/0300-0399/0326.Power of Three/Solution.rs
new file mode 100644
index 0000000000000..a113ed1db3b9a
--- /dev/null
+++ b/solution/0300-0399/0326.Power of Three/Solution.rs
@@ -0,0 +1,11 @@
+impl Solution {
+ pub fn is_power_of_three(mut n: i32) -> bool {
+ while n > 2 {
+ if n % 3 != 0 {
+ return false;
+ }
+ n /= 3;
+ }
+ n == 1
+ }
+}
diff --git a/solution/0300-0399/0326.Power of Three/Solution.ts b/solution/0300-0399/0326.Power of Three/Solution.ts
index df4ff57647996..6c2b7a9a73448 100644
--- a/solution/0300-0399/0326.Power of Three/Solution.ts
+++ b/solution/0300-0399/0326.Power of Three/Solution.ts
@@ -1,3 +1,9 @@
function isPowerOfThree(n: number): boolean {
- return n > 0 && 1162261467 % n == 0;
+ while (n > 2) {
+ if (n % 3 !== 0) {
+ return false;
+ }
+ n = Math.floor(n / 3);
+ }
+ return n === 1;
}
diff --git a/solution/0300-0399/0326.Power of Three/Solution2.js b/solution/0300-0399/0326.Power of Three/Solution2.js
new file mode 100644
index 0000000000000..7b9ee58149669
--- /dev/null
+++ b/solution/0300-0399/0326.Power of Three/Solution2.js
@@ -0,0 +1,7 @@
+/**
+ * @param {number} n
+ * @return {boolean}
+ */
+var isPowerOfThree = function (n) {
+ return n > 0 && 1162261467 % n == 0;
+};
diff --git a/solution/0300-0399/0326.Power of Three/Solution2.rs b/solution/0300-0399/0326.Power of Three/Solution2.rs
new file mode 100644
index 0000000000000..622269a4a8148
--- /dev/null
+++ b/solution/0300-0399/0326.Power of Three/Solution2.rs
@@ -0,0 +1,5 @@
+impl Solution {
+ pub fn is_power_of_three(mut n: i32) -> bool {
+ n > 0 && 1162261467 % n == 0
+ }
+}
diff --git a/solution/0300-0399/0326.Power of Three/Solution2.ts b/solution/0300-0399/0326.Power of Three/Solution2.ts
new file mode 100644
index 0000000000000..df4ff57647996
--- /dev/null
+++ b/solution/0300-0399/0326.Power of Three/Solution2.ts
@@ -0,0 +1,3 @@
+function isPowerOfThree(n: number): boolean {
+ return n > 0 && 1162261467 % n == 0;
+}
diff --git a/solution/0300-0399/0328.Odd Even Linked List/README.md b/solution/0300-0399/0328.Odd Even Linked List/README.md
index ecec1ac6f1cf8..c9165d73e2ebb 100644
--- a/solution/0300-0399/0328.Odd Even Linked List/README.md
+++ b/solution/0300-0399/0328.Odd Even Linked List/README.md
@@ -16,7 +16,7 @@ tags:
-
给定单链表的头节点 head ,将所有索引为奇数的节点和索引为偶数的节点分别组合在一起,然后返回重新排序的列表。
+
给定单链表的头节点 head ,将所有索引为奇数的节点和索引为偶数的节点分别分组,保持它们原有的相对顺序,然后把偶数索引节点分组连接到奇数索引节点分组之后,返回重新排序的链表。
第一个节点的索引被认为是 奇数 , 第二个节点的索引为 偶数 ,以此类推。
diff --git a/solution/0300-0399/0342.Power of Four/README.md b/solution/0300-0399/0342.Power of Four/README.md
index 1e71bac29bc3f..df7c9f80aa146 100644
--- a/solution/0300-0399/0342.Power of Four/README.md
+++ b/solution/0300-0399/0342.Power of Four/README.md
@@ -65,9 +65,9 @@ tags:
### 方法一:位运算
-如果一个数是 4 的幂次方,那么这个数必须是大于 $0$ 的。不妨假设这个数是 $4^x$,即 $2^{2x}$,那么这个数的二进制表示中有且仅有一个 $1$,且这个 $1$ 出现在偶数位上。
+如果一个数是 $4$ 的幂次方,那么这个数必须是大于 $0$ 的。不妨假设这个数是 $4^x$,即 $2^{2x}$,那么这个数的二进制表示中有且仅有一个 $1$,且这个 $1$ 出现在偶数位上。
-因此,我们首先判断这个数是否大于 $0$,然后判断这个数是否是 $2^{2x}$,即 $n$ 与 $n-1$ 的按位与结果是否为 $0$,最后判断这个数的 $1$ 是否出现在偶数位上,即 $n$ 与 $\textit{0xAAAAAAAA}$ 的按位与结果是否为 $0$。如果这三个条件都满足,那么这个数就是 4 的幂次方。
+因此,我们首先判断这个数是否大于 $0$,然后判断这个数是否是 $2^{2x}$,即 $n$ 与 $n-1$ 的按位与结果是否为 $0$,最后判断这个数的 $1$ 是否出现在偶数位上,即 $n$ 与 $\textit{0xAAAAAAAA}$ 的按位与结果是否为 $0$。如果这三个条件都满足,那么这个数就是 $4$ 的幂次方。
时间复杂度 $O(1)$,空间复杂度 $O(1)$。
@@ -118,6 +118,16 @@ function isPowerOfFour(n: number): boolean {
}
```
+#### Rust
+
+```rust
+impl Solution {
+ pub fn is_power_of_four(n: i32) -> bool {
+ n > 0 && (n & (n - 1)) == 0 && (n & 0xaaaaaaaa_u32 as i32) == 0
+ }
+}
+```
+
#### JavaScript
```js
@@ -130,6 +140,16 @@ var isPowerOfFour = function (n) {
};
```
+#### C#
+
+```cs
+public class Solution {
+ public bool IsPowerOfFour(int n) {
+ return n > 0 && (n & (n - 1)) == 0 && (n & 0xaaaaaaaa) == 0;
+ }
+}
+```
+
diff --git a/solution/0300-0399/0342.Power of Four/README_EN.md b/solution/0300-0399/0342.Power of Four/README_EN.md
index d74f994dc6c3d..82a3a2ce57127 100644
--- a/solution/0300-0399/0342.Power of Four/README_EN.md
+++ b/solution/0300-0399/0342.Power of Four/README_EN.md
@@ -51,9 +51,9 @@ tags:
### Solution 1: Bit Manipulation
-If a number is a power of 4, then it must be greater than $0$. Suppose this number is $4^x$, which is $2^{2x}$. Therefore, its binary representation has only one $1$, and this $1$ appears at an even position.
+If a number is a power of $4$, then it must be greater than $0$. Suppose this number is $4^x$, which is $2^{2x}$. Therefore, its binary representation has only one $1$, and this $1$ appears at an even position.
-First, we check if the number is greater than $0$. Then, we verify if the number is $2^{2x}$ by checking if the bitwise AND of $n$ and $n-1$ is $0$. Finally, we check if the $1$ appears at an even position by verifying if the bitwise AND of $n$ and $\textit{0xAAAAAAAA}$ is $0$. If all three conditions are met, then the number is a power of 4.
+First, we check if the number is greater than $0$. Then, we verify if the number is $2^{2x}$ by checking if the bitwise AND of $n$ and $n-1$ is $0$. Finally, we check if the $1$ appears at an even position by verifying if the bitwise AND of $n$ and $\textit{0xAAAAAAAA}$ is $0$. If all three conditions are met, then the number is a power of $4$.
The time complexity is $O(1)$, and the space complexity is $O(1)$.
@@ -104,6 +104,16 @@ function isPowerOfFour(n: number): boolean {
}
```
+#### Rust
+
+```rust
+impl Solution {
+ pub fn is_power_of_four(n: i32) -> bool {
+ n > 0 && (n & (n - 1)) == 0 && (n & 0xaaaaaaaa_u32 as i32) == 0
+ }
+}
+```
+
#### JavaScript
```js
@@ -116,6 +126,16 @@ var isPowerOfFour = function (n) {
};
```
+#### C#
+
+```cs
+public class Solution {
+ public bool IsPowerOfFour(int n) {
+ return n > 0 && (n & (n - 1)) == 0 && (n & 0xaaaaaaaa) == 0;
+ }
+}
+```
+
diff --git a/solution/0300-0399/0342.Power of Four/Solution.cs b/solution/0300-0399/0342.Power of Four/Solution.cs
new file mode 100644
index 0000000000000..bde55eb3764d1
--- /dev/null
+++ b/solution/0300-0399/0342.Power of Four/Solution.cs
@@ -0,0 +1,5 @@
+public class Solution {
+ public bool IsPowerOfFour(int n) {
+ return n > 0 && (n & (n - 1)) == 0 && (n & 0xaaaaaaaa) == 0;
+ }
+}
diff --git a/solution/0300-0399/0342.Power of Four/Solution.rs b/solution/0300-0399/0342.Power of Four/Solution.rs
new file mode 100644
index 0000000000000..90bd2af384062
--- /dev/null
+++ b/solution/0300-0399/0342.Power of Four/Solution.rs
@@ -0,0 +1,5 @@
+impl Solution {
+ pub fn is_power_of_four(n: i32) -> bool {
+ n > 0 && (n & (n - 1)) == 0 && (n & 0xaaaaaaaa_u32 as i32) == 0
+ }
+}
diff --git a/solution/0300-0399/0346.Moving Average from Data Stream/README.md b/solution/0300-0399/0346.Moving Average from Data Stream/README.md
index efb6c61d85aec..2a781655610a2 100644
--- a/solution/0300-0399/0346.Moving Average from Data Stream/README.md
+++ b/solution/0300-0399/0346.Moving Average from Data Stream/README.md
@@ -65,23 +65,30 @@ movingAverage.next(5); // 返回 6.0 = (10 + 3 + 5) / 3
### 方法一:循环数组
+我们定义一个变量 $\textit{s}$,用于计算当前最后 $\textit{size}$ 个元素的和,用一个变量 $\textit{cnt}$ 记录当前元素的总数。另外,我们用一个长度为 $\textit{size}$ 的数组 $\textit{data}$ 记录每个位置的元素对应的值。
+
+调用 $\textit{next}$ 函数时,我们先计算出 $\textit{val}$ 要存放的下标 $i$,然后我们更新元素和 $s$,并且将下标 $i$ 处的值设置为 $\textit{val}$,同时将元素的个数加一。最后,我们返回 $\frac{s}{\min(\textit{cnt}, \textit{size})}$ 的值即可。
+
+时间复杂度 $O(1)$,空间复杂度 $O(n)$,其中 $n$ 是题目给定的整数 $\textit{size}$。
+
#### Python3
```python
class MovingAverage:
+
def __init__(self, size: int):
- self.arr = [0] * size
self.s = 0
+ self.data = [0] * size
self.cnt = 0
def next(self, val: int) -> float:
- idx = self.cnt % len(self.arr)
- self.s += val - self.arr[idx]
- self.arr[idx] = val
+ i = self.cnt % len(self.data)
+ self.s += val - self.data[i]
+ self.data[i] = val
self.cnt += 1
- return self.s / min(self.cnt, len(self.arr))
+ return self.s / min(self.cnt, len(self.data))
# Your MovingAverage object will be instantiated and called as such:
@@ -93,20 +100,20 @@ class MovingAverage:
```java
class MovingAverage {
- private int[] arr;
private int s;
private int cnt;
+ private int[] data;
public MovingAverage(int size) {
- arr = new int[size];
+ data = new int[size];
}
public double next(int val) {
- int idx = cnt % arr.length;
- s += val - arr[idx];
- arr[idx] = val;
+ int i = cnt % data.length;
+ s += val - data[i];
+ data[i] = val;
++cnt;
- return s * 1.0 / Math.min(cnt, arr.length);
+ return s * 1.0 / Math.min(cnt, data.length);
}
}
@@ -123,21 +130,21 @@ class MovingAverage {
class MovingAverage {
public:
MovingAverage(int size) {
- arr.resize(size);
+ data.resize(size);
}
double next(int val) {
- int idx = cnt % arr.size();
- s += val - arr[idx];
- arr[idx] = val;
+ int i = cnt % data.size();
+ s += val - data[i];
+ data[i] = val;
++cnt;
- return (double) s / min(cnt, (int) arr.size());
+ return s * 1.0 / min(cnt, (int) data.size());
}
private:
- vector arr;
- int cnt = 0;
int s = 0;
+ int cnt = 0;
+ vector data;
};
/**
@@ -151,22 +158,23 @@ private:
```go
type MovingAverage struct {
- arr []int
- cnt int
- s int
+ s int
+ cnt int
+ data []int
}
func Constructor(size int) MovingAverage {
- arr := make([]int, size)
- return MovingAverage{arr, 0, 0}
+ return MovingAverage{
+ data: make([]int, size),
+ }
}
func (this *MovingAverage) Next(val int) float64 {
- idx := this.cnt % len(this.arr)
- this.s += val - this.arr[idx]
- this.arr[idx] = val
+ i := this.cnt % len(this.data)
+ this.s += val - this.data[i]
+ this.data[i] = val
this.cnt++
- return float64(this.s) / float64(min(this.cnt, len(this.arr)))
+ return float64(this.s) / float64(min(this.cnt, len(this.data)))
}
/**
@@ -176,6 +184,34 @@ func (this *MovingAverage) Next(val int) float64 {
*/
```
+#### TypeScript
+
+```ts
+class MovingAverage {
+ private s: number = 0;
+ private cnt: number = 0;
+ private data: number[];
+
+ constructor(size: number) {
+ this.data = Array(size).fill(0);
+ }
+
+ next(val: number): number {
+ const i = this.cnt % this.data.length;
+ this.s += val - this.data[i];
+ this.data[i] = val;
+ this.cnt++;
+ return this.s / Math.min(this.cnt, this.data.length);
+ }
+}
+
+/**
+ * Your MovingAverage object will be instantiated and called as such:
+ * var obj = new MovingAverage(size)
+ * var param_1 = obj.next(val)
+ */
+```
+
@@ -184,6 +220,12 @@ func (this *MovingAverage) Next(val int) float64 {
### 方法二:队列
+我们可以使用一个队列 $\textit{q}$ 来存储最后 $\textit{size}$ 个元素,同时用一个变量 $\textit{s}$ 来记录这 $\textit{size}$ 个元素的和。
+
+在调用 $\textit{next}$ 函数时,我们首先判断队列 $\textit{q}$ 的长度是否等于 $\textit{size}$,如果等于 $\textit{size}$,则将队列 $\textit{q}$ 的头部元素出队,并且更新 $\textit{s}$ 的值。然后将 $\textit{val}$ 入队,并且更新 $\textit{s}$ 的值。最后返回 $\frac{s}{\text{len}(q)}$ 的值即可。
+
+时间复杂度 $O(1)$,空间复杂度 $O(n)$,其中 $n$ 是题目给定的整数 $\textit{size}$。
+
#### Python3
@@ -299,6 +341,35 @@ func (this *MovingAverage) Next(val int) float64 {
*/
```
+#### TypeScript
+
+```ts
+class MovingAverage {
+ private q: number[] = [];
+ private s: number = 0;
+ private n: number;
+
+ constructor(size: number) {
+ this.n = size;
+ }
+
+ next(val: number): number {
+ if (this.q.length === this.n) {
+ this.s -= this.q.shift()!;
+ }
+ this.q.push(val);
+ this.s += val;
+ return this.s / this.q.length;
+ }
+}
+
+/**
+ * Your MovingAverage object will be instantiated and called as such:
+ * var obj = new MovingAverage(size)
+ * var param_1 = obj.next(val)
+ */
+```
+
diff --git a/solution/0300-0399/0346.Moving Average from Data Stream/README_EN.md b/solution/0300-0399/0346.Moving Average from Data Stream/README_EN.md
index e6c04298ab273..68d0a084b5d68 100644
--- a/solution/0300-0399/0346.Moving Average from Data Stream/README_EN.md
+++ b/solution/0300-0399/0346.Moving Average from Data Stream/README_EN.md
@@ -61,7 +61,13 @@ movingAverage.next(5); // return 6.0 = (10 + 3 + 5) / 3
-### Solution 1
+### Solution 1: Circular Array
+
+We define a variable $\textit{s}$ to calculate the sum of the last $\textit{size}$ elements, and a variable $\textit{cnt}$ to record the total number of current elements. Additionally, we use an array $\textit{data}$ of length $\textit{size}$ to record the value of each element at each position.
+
+When calling the $\textit{next}$ function, we first calculate the index $i$ where $\textit{val}$ should be stored, then update the sum $s$, set the value at index $i$ to $\textit{val}$, and increment the element count by one. Finally, we return the value of $\frac{s}{\min(\textit{cnt}, \textit{size})}$.
+
+The time complexity is $O(1)$, and the space complexity is $O(n)$, where $n$ is the integer $\textit{size}$ given in the problem.
@@ -69,17 +75,18 @@ movingAverage.next(5); // return 6.0 = (10 + 3 + 5) / 3
```python
class MovingAverage:
+
def __init__(self, size: int):
- self.arr = [0] * size
self.s = 0
+ self.data = [0] * size
self.cnt = 0
def next(self, val: int) -> float:
- idx = self.cnt % len(self.arr)
- self.s += val - self.arr[idx]
- self.arr[idx] = val
+ i = self.cnt % len(self.data)
+ self.s += val - self.data[i]
+ self.data[i] = val
self.cnt += 1
- return self.s / min(self.cnt, len(self.arr))
+ return self.s / min(self.cnt, len(self.data))
# Your MovingAverage object will be instantiated and called as such:
@@ -91,20 +98,20 @@ class MovingAverage:
```java
class MovingAverage {
- private int[] arr;
private int s;
private int cnt;
+ private int[] data;
public MovingAverage(int size) {
- arr = new int[size];
+ data = new int[size];
}
public double next(int val) {
- int idx = cnt % arr.length;
- s += val - arr[idx];
- arr[idx] = val;
+ int i = cnt % data.length;
+ s += val - data[i];
+ data[i] = val;
++cnt;
- return s * 1.0 / Math.min(cnt, arr.length);
+ return s * 1.0 / Math.min(cnt, data.length);
}
}
@@ -121,21 +128,21 @@ class MovingAverage {
class MovingAverage {
public:
MovingAverage(int size) {
- arr.resize(size);
+ data.resize(size);
}
double next(int val) {
- int idx = cnt % arr.size();
- s += val - arr[idx];
- arr[idx] = val;
+ int i = cnt % data.size();
+ s += val - data[i];
+ data[i] = val;
++cnt;
- return (double) s / min(cnt, (int) arr.size());
+ return s * 1.0 / min(cnt, (int) data.size());
}
private:
- vector arr;
- int cnt = 0;
int s = 0;
+ int cnt = 0;
+ vector data;
};
/**
@@ -149,22 +156,23 @@ private:
```go
type MovingAverage struct {
- arr []int
- cnt int
- s int
+ s int
+ cnt int
+ data []int
}
func Constructor(size int) MovingAverage {
- arr := make([]int, size)
- return MovingAverage{arr, 0, 0}
+ return MovingAverage{
+ data: make([]int, size),
+ }
}
func (this *MovingAverage) Next(val int) float64 {
- idx := this.cnt % len(this.arr)
- this.s += val - this.arr[idx]
- this.arr[idx] = val
+ i := this.cnt % len(this.data)
+ this.s += val - this.data[i]
+ this.data[i] = val
this.cnt++
- return float64(this.s) / float64(min(this.cnt, len(this.arr)))
+ return float64(this.s) / float64(min(this.cnt, len(this.data)))
}
/**
@@ -174,13 +182,47 @@ func (this *MovingAverage) Next(val int) float64 {
*/
```
+#### TypeScript
+
+```ts
+class MovingAverage {
+ private s: number = 0;
+ private cnt: number = 0;
+ private data: number[];
+
+ constructor(size: number) {
+ this.data = Array(size).fill(0);
+ }
+
+ next(val: number): number {
+ const i = this.cnt % this.data.length;
+ this.s += val - this.data[i];
+ this.data[i] = val;
+ this.cnt++;
+ return this.s / Math.min(this.cnt, this.data.length);
+ }
+}
+
+/**
+ * Your MovingAverage object will be instantiated and called as such:
+ * var obj = new MovingAverage(size)
+ * var param_1 = obj.next(val)
+ */
+```
+
-### Solution 2
+### Solution 2: Queue
+
+We can use a queue $\textit{q}$ to store the last $\textit{size}$ elements, and a variable $\textit{s}$ to record the sum of these $\textit{size}$ elements.
+
+When calling the $\textit{next}$ function, we first check if the length of the queue $\textit{q}$ is equal to $\textit{size}$. If it is, we dequeue the front element of the queue $\textit{q}$ and update the value of $\textit{s}$. Then we enqueue $\textit{val}$ and update the value of $\textit{s}$. Finally, we return the value of $\frac{s}{\text{len}(q)}$.
+
+The time complexity is $O(1)$, and the space complexity is $O(n)$, where $n$ is the integer $\textit{size}$ given in the problem.
@@ -297,6 +339,35 @@ func (this *MovingAverage) Next(val int) float64 {
*/
```
+#### TypeScript
+
+```ts
+class MovingAverage {
+ private q: number[] = [];
+ private s: number = 0;
+ private n: number;
+
+ constructor(size: number) {
+ this.n = size;
+ }
+
+ next(val: number): number {
+ if (this.q.length === this.n) {
+ this.s -= this.q.shift()!;
+ }
+ this.q.push(val);
+ this.s += val;
+ return this.s / this.q.length;
+ }
+}
+
+/**
+ * Your MovingAverage object will be instantiated and called as such:
+ * var obj = new MovingAverage(size)
+ * var param_1 = obj.next(val)
+ */
+```
+
diff --git a/solution/0300-0399/0346.Moving Average from Data Stream/Solution.cpp b/solution/0300-0399/0346.Moving Average from Data Stream/Solution.cpp
index 2a9a16e4faee5..6576b9dc8630a 100644
--- a/solution/0300-0399/0346.Moving Average from Data Stream/Solution.cpp
+++ b/solution/0300-0399/0346.Moving Average from Data Stream/Solution.cpp
@@ -1,21 +1,21 @@
class MovingAverage {
public:
MovingAverage(int size) {
- arr.resize(size);
+ data.resize(size);
}
double next(int val) {
- int idx = cnt % arr.size();
- s += val - arr[idx];
- arr[idx] = val;
+ int i = cnt % data.size();
+ s += val - data[i];
+ data[i] = val;
++cnt;
- return (double) s / min(cnt, (int) arr.size());
+ return s * 1.0 / min(cnt, (int) data.size());
}
private:
- vector arr;
- int cnt = 0;
int s = 0;
+ int cnt = 0;
+ vector data;
};
/**
diff --git a/solution/0300-0399/0346.Moving Average from Data Stream/Solution.go b/solution/0300-0399/0346.Moving Average from Data Stream/Solution.go
index ec727ba1c0a94..5dcabe9e9361e 100644
--- a/solution/0300-0399/0346.Moving Average from Data Stream/Solution.go
+++ b/solution/0300-0399/0346.Moving Average from Data Stream/Solution.go
@@ -1,20 +1,21 @@
type MovingAverage struct {
- arr []int
- cnt int
- s int
+ s int
+ cnt int
+ data []int
}
func Constructor(size int) MovingAverage {
- arr := make([]int, size)
- return MovingAverage{arr, 0, 0}
+ return MovingAverage{
+ data: make([]int, size),
+ }
}
func (this *MovingAverage) Next(val int) float64 {
- idx := this.cnt % len(this.arr)
- this.s += val - this.arr[idx]
- this.arr[idx] = val
+ i := this.cnt % len(this.data)
+ this.s += val - this.data[i]
+ this.data[i] = val
this.cnt++
- return float64(this.s) / float64(min(this.cnt, len(this.arr)))
+ return float64(this.s) / float64(min(this.cnt, len(this.data)))
}
/**
diff --git a/solution/0300-0399/0346.Moving Average from Data Stream/Solution.java b/solution/0300-0399/0346.Moving Average from Data Stream/Solution.java
index f9e90a100d6e2..d53353922e460 100644
--- a/solution/0300-0399/0346.Moving Average from Data Stream/Solution.java
+++ b/solution/0300-0399/0346.Moving Average from Data Stream/Solution.java
@@ -1,18 +1,18 @@
class MovingAverage {
- private int[] arr;
private int s;
private int cnt;
+ private int[] data;
public MovingAverage(int size) {
- arr = new int[size];
+ data = new int[size];
}
public double next(int val) {
- int idx = cnt % arr.length;
- s += val - arr[idx];
- arr[idx] = val;
+ int i = cnt % data.length;
+ s += val - data[i];
+ data[i] = val;
++cnt;
- return s * 1.0 / Math.min(cnt, arr.length);
+ return s * 1.0 / Math.min(cnt, data.length);
}
}
diff --git a/solution/0300-0399/0346.Moving Average from Data Stream/Solution.py b/solution/0300-0399/0346.Moving Average from Data Stream/Solution.py
index 883ed1d768a19..edc9e4f84623b 100644
--- a/solution/0300-0399/0346.Moving Average from Data Stream/Solution.py
+++ b/solution/0300-0399/0346.Moving Average from Data Stream/Solution.py
@@ -1,15 +1,16 @@
class MovingAverage:
+
def __init__(self, size: int):
- self.arr = [0] * size
self.s = 0
+ self.data = [0] * size
self.cnt = 0
def next(self, val: int) -> float:
- idx = self.cnt % len(self.arr)
- self.s += val - self.arr[idx]
- self.arr[idx] = val
+ i = self.cnt % len(self.data)
+ self.s += val - self.data[i]
+ self.data[i] = val
self.cnt += 1
- return self.s / min(self.cnt, len(self.arr))
+ return self.s / min(self.cnt, len(self.data))
# Your MovingAverage object will be instantiated and called as such:
diff --git a/solution/0300-0399/0346.Moving Average from Data Stream/Solution.ts b/solution/0300-0399/0346.Moving Average from Data Stream/Solution.ts
new file mode 100644
index 0000000000000..db54902553b61
--- /dev/null
+++ b/solution/0300-0399/0346.Moving Average from Data Stream/Solution.ts
@@ -0,0 +1,23 @@
+class MovingAverage {
+ private s: number = 0;
+ private cnt: number = 0;
+ private data: number[];
+
+ constructor(size: number) {
+ this.data = Array(size).fill(0);
+ }
+
+ next(val: number): number {
+ const i = this.cnt % this.data.length;
+ this.s += val - this.data[i];
+ this.data[i] = val;
+ this.cnt++;
+ return this.s / Math.min(this.cnt, this.data.length);
+ }
+}
+
+/**
+ * Your MovingAverage object will be instantiated and called as such:
+ * var obj = new MovingAverage(size)
+ * var param_1 = obj.next(val)
+ */
diff --git a/solution/0300-0399/0346.Moving Average from Data Stream/Solution2.ts b/solution/0300-0399/0346.Moving Average from Data Stream/Solution2.ts
new file mode 100644
index 0000000000000..52a3940d0d2e8
--- /dev/null
+++ b/solution/0300-0399/0346.Moving Average from Data Stream/Solution2.ts
@@ -0,0 +1,24 @@
+class MovingAverage {
+ private q: number[] = [];
+ private s: number = 0;
+ private n: number;
+
+ constructor(size: number) {
+ this.n = size;
+ }
+
+ next(val: number): number {
+ if (this.q.length === this.n) {
+ this.s -= this.q.shift()!;
+ }
+ this.q.push(val);
+ this.s += val;
+ return this.s / this.q.length;
+ }
+}
+
+/**
+ * Your MovingAverage object will be instantiated and called as such:
+ * var obj = new MovingAverage(size)
+ * var param_1 = obj.next(val)
+ */
diff --git a/solution/0300-0399/0348.Design Tic-Tac-Toe/README.md b/solution/0300-0399/0348.Design Tic-Tac-Toe/README.md
index c3bdea5faf274..a9b134fb52acd 100644
--- a/solution/0300-0399/0348.Design Tic-Tac-Toe/README.md
+++ b/solution/0300-0399/0348.Design Tic-Tac-Toe/README.md
@@ -20,7 +20,7 @@ tags:
-
请在 n × n 的棋盘上,实现一个判定井字棋(Tic-Tac-Toe)胜负的神器,判断每一次玩家落子后,是否有胜出的玩家。
+
请在 n × n 的棋盘上,实现一个判定井字棋(Tic-Tac-Toe)胜负的神器,判断每一次玩家落子后,是否有胜出的玩家。
在这个井字棋游戏中,会有 2 名玩家,他们将轮流在棋盘上放置自己的棋子。
@@ -34,7 +34,8 @@ tags:
示例:
-
给定棋盘边长 n = 3, 玩家 1 的棋子符号是 "X",玩家 2 的棋子符号是 "O"。
+
+给定棋盘边长 n = 3, 玩家 1 的棋子符号是 "X",玩家 2 的棋子符号是 "O"。
TicTacToe toe = new TicTacToe(3);
@@ -76,7 +77,17 @@ toe.move(2, 1, 1); -> 函数返回 1 (此时,玩家 1 赢得了该场比赛
-
进阶:
+
提示:
+
+
+
2 <= n <= 100
+
玩家是 1 或 2。
+
0 <= row, col < n
+
每次调用 move 时 (row, col) 都是不同的。
+
最多调用 moven2 次。
+
+
+
进阶:
您有没有可能将每一步的 move() 操作优化到比 O(n2) 更快吗?
diff --git a/solution/0300-0399/0368.Largest Divisible Subset/README.md b/solution/0300-0399/0368.Largest Divisible Subset/README.md
index b3d3b284eedf3..223b2225ee2be 100644
--- a/solution/0300-0399/0368.Largest Divisible Subset/README.md
+++ b/solution/0300-0399/0368.Largest Divisible Subset/README.md
@@ -141,7 +141,7 @@ class Solution {
class Solution {
public:
vector largestDivisibleSubset(vector& nums) {
- sort(nums.begin(), nums.end());
+ ranges::sort(nums);
int n = nums.size();
int f[n];
int k = 0;
@@ -201,6 +201,79 @@ func largestDivisibleSubset(nums []int) (ans []int) {
}
```
+#### TypeScript
+
+```ts
+function largestDivisibleSubset(nums: number[]): number[] {
+ nums.sort((a, b) => a - b);
+ const n = nums.length;
+ const f: number[] = Array(n).fill(1);
+ let k = 0;
+
+ for (let i = 0; i < n; ++i) {
+ for (let j = 0; j < i; ++j) {
+ if (nums[i] % nums[j] === 0) {
+ f[i] = Math.max(f[i], f[j] + 1);
+ }
+ }
+ if (f[k] < f[i]) {
+ k = i;
+ }
+ }
+
+ let m = f[k];
+ const ans: number[] = [];
+ for (let i = k; m > 0; --i) {
+ if (nums[k] % nums[i] === 0 && f[i] === m) {
+ ans.push(nums[i]);
+ k = i;
+ --m;
+ }
+ }
+
+ return ans;
+}
+```
+
+#### Rust
+
+```rust
+impl Solution {
+ pub fn largest_divisible_subset(nums: Vec) -> Vec {
+ let mut nums = nums;
+ nums.sort();
+
+ let n = nums.len();
+ let mut f = vec![1; n];
+ let mut k = 0;
+
+ for i in 0..n {
+ for j in 0..i {
+ if nums[i] % nums[j] == 0 {
+ f[i] = f[i].max(f[j] + 1);
+ }
+ }
+ if f[k] < f[i] {
+ k = i;
+ }
+ }
+
+ let mut m = f[k];
+ let mut ans = Vec::new();
+
+ for i in (0..=k).rev() {
+ if nums[k] % nums[i] == 0 && f[i] == m {
+ ans.push(nums[i]);
+ k = i;
+ m -= 1;
+ }
+ }
+
+ ans
+ }
+}
+```
+
diff --git a/solution/0300-0399/0368.Largest Divisible Subset/README_EN.md b/solution/0300-0399/0368.Largest Divisible Subset/README_EN.md
index dc4c6e2a9992c..e3c4350b3935a 100644
--- a/solution/0300-0399/0368.Largest Divisible Subset/README_EN.md
+++ b/solution/0300-0399/0368.Largest Divisible Subset/README_EN.md
@@ -129,7 +129,7 @@ class Solution {
class Solution {
public:
vector largestDivisibleSubset(vector& nums) {
- sort(nums.begin(), nums.end());
+ ranges::sort(nums);
int n = nums.size();
int f[n];
int k = 0;
@@ -189,6 +189,79 @@ func largestDivisibleSubset(nums []int) (ans []int) {
}
```
+#### TypeScript
+
+```ts
+function largestDivisibleSubset(nums: number[]): number[] {
+ nums.sort((a, b) => a - b);
+ const n = nums.length;
+ const f: number[] = Array(n).fill(1);
+ let k = 0;
+
+ for (let i = 0; i < n; ++i) {
+ for (let j = 0; j < i; ++j) {
+ if (nums[i] % nums[j] === 0) {
+ f[i] = Math.max(f[i], f[j] + 1);
+ }
+ }
+ if (f[k] < f[i]) {
+ k = i;
+ }
+ }
+
+ let m = f[k];
+ const ans: number[] = [];
+ for (let i = k; m > 0; --i) {
+ if (nums[k] % nums[i] === 0 && f[i] === m) {
+ ans.push(nums[i]);
+ k = i;
+ --m;
+ }
+ }
+
+ return ans;
+}
+```
+
+#### Rust
+
+```rust
+impl Solution {
+ pub fn largest_divisible_subset(nums: Vec) -> Vec {
+ let mut nums = nums;
+ nums.sort();
+
+ let n = nums.len();
+ let mut f = vec![1; n];
+ let mut k = 0;
+
+ for i in 0..n {
+ for j in 0..i {
+ if nums[i] % nums[j] == 0 {
+ f[i] = f[i].max(f[j] + 1);
+ }
+ }
+ if f[k] < f[i] {
+ k = i;
+ }
+ }
+
+ let mut m = f[k];
+ let mut ans = Vec::new();
+
+ for i in (0..=k).rev() {
+ if nums[k] % nums[i] == 0 && f[i] == m {
+ ans.push(nums[i]);
+ k = i;
+ m -= 1;
+ }
+ }
+
+ ans
+ }
+}
+```
+
diff --git a/solution/0300-0399/0368.Largest Divisible Subset/Solution.cpp b/solution/0300-0399/0368.Largest Divisible Subset/Solution.cpp
index 769a58dba948a..b6834c46b9c0a 100644
--- a/solution/0300-0399/0368.Largest Divisible Subset/Solution.cpp
+++ b/solution/0300-0399/0368.Largest Divisible Subset/Solution.cpp
@@ -1,7 +1,7 @@
class Solution {
public:
vector largestDivisibleSubset(vector& nums) {
- sort(nums.begin(), nums.end());
+ ranges::sort(nums);
int n = nums.size();
int f[n];
int k = 0;
diff --git a/solution/0300-0399/0368.Largest Divisible Subset/Solution.rs b/solution/0300-0399/0368.Largest Divisible Subset/Solution.rs
new file mode 100644
index 0000000000000..337f4e2a2c6f4
--- /dev/null
+++ b/solution/0300-0399/0368.Largest Divisible Subset/Solution.rs
@@ -0,0 +1,34 @@
+impl Solution {
+ pub fn largest_divisible_subset(nums: Vec) -> Vec {
+ let mut nums = nums;
+ nums.sort();
+
+ let n = nums.len();
+ let mut f = vec![1; n];
+ let mut k = 0;
+
+ for i in 0..n {
+ for j in 0..i {
+ if nums[i] % nums[j] == 0 {
+ f[i] = f[i].max(f[j] + 1);
+ }
+ }
+ if f[k] < f[i] {
+ k = i;
+ }
+ }
+
+ let mut m = f[k];
+ let mut ans = Vec::new();
+
+ for i in (0..=k).rev() {
+ if nums[k] % nums[i] == 0 && f[i] == m {
+ ans.push(nums[i]);
+ k = i;
+ m -= 1;
+ }
+ }
+
+ ans
+ }
+}
diff --git a/solution/0300-0399/0368.Largest Divisible Subset/Solution.ts b/solution/0300-0399/0368.Largest Divisible Subset/Solution.ts
new file mode 100644
index 0000000000000..7afb250a3a280
--- /dev/null
+++ b/solution/0300-0399/0368.Largest Divisible Subset/Solution.ts
@@ -0,0 +1,29 @@
+function largestDivisibleSubset(nums: number[]): number[] {
+ nums.sort((a, b) => a - b);
+ const n = nums.length;
+ const f: number[] = Array(n).fill(1);
+ let k = 0;
+
+ for (let i = 0; i < n; ++i) {
+ for (let j = 0; j < i; ++j) {
+ if (nums[i] % nums[j] === 0) {
+ f[i] = Math.max(f[i], f[j] + 1);
+ }
+ }
+ if (f[k] < f[i]) {
+ k = i;
+ }
+ }
+
+ let m = f[k];
+ const ans: number[] = [];
+ for (let i = k; m > 0; --i) {
+ if (nums[k] % nums[i] === 0 && f[i] === m) {
+ ans.push(nums[i]);
+ k = i;
+ --m;
+ }
+ }
+
+ return ans;
+}
diff --git a/solution/0300-0399/0369.Plus One Linked List/README.md b/solution/0300-0399/0369.Plus One Linked List/README.md
index 95eebe6928d74..078c4033d9a67 100644
--- a/solution/0300-0399/0369.Plus One Linked List/README.md
+++ b/solution/0300-0399/0369.Plus One Linked List/README.md
@@ -57,13 +57,13 @@ tags:
### 方法一:链表遍历
-我们先设置一个虚拟头节点 `dummy`,初始值为 $0$,指向链表头节点 `head`。
+我们先设置一个虚拟头节点 $\textit{dummy}$,初始时 $\textit{dummy}$ 的值为 $0$,并且 $\textit{dummy}$ 的后继节点为链表 $\textit{head}$。
-然后从链表头节点开始遍历,找出链表最后一个值不等于 $9$ 的节点 `target`,将 `target` 的值加 $1$。接着将 `target` 之后的所有节点值置为 $0$。
+接下来,我们从虚拟头节点开始遍历链表,找到最后一个不为 $9$ 的节点,将其值加 $1$,并将该节点之后的所有节点的值置为 $0$。
-需要注意的是,如果链表中所有节点值都为 $9$,那么遍历结束后,`target` 会指向空节点,这时我们需要将 `dummy` 的值加 $1$,然后返回 `dummy`,否则返回 `dummy` 的下一个节点。
+最后,我们判断虚拟头节点的值是否为 $1$,如果为 $1$,则返回 $\textit{dummy}$,否则返回 $\textit{dummy}$ 的后继节点。
-时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为链表的长度。
+时间复杂度 $O(n)$,其中 $n$ 是链表的长度。空间复杂度 $O(1)$。
@@ -76,7 +76,7 @@ tags:
# self.val = val
# self.next = next
class Solution:
- def plusOne(self, head: ListNode) -> ListNode:
+ def plusOne(self, head: Optional[ListNode]) -> Optional[ListNode]:
dummy = ListNode(0, head)
target = dummy
while head:
@@ -143,17 +143,16 @@ public:
ListNode* plusOne(ListNode* head) {
ListNode* dummy = new ListNode(0, head);
ListNode* target = dummy;
- while (head) {
- if (head->val != 9) target = head;
- head = head->next;
+ for (; head; head = head->next) {
+ if (head->val != 9) {
+ target = head;
+ }
}
- ++target->val;
- target = target->next;
- while (target) {
+ target->val++;
+ for (target = target->next; target; target = target->next) {
target->val = 0;
- target = target->next;
}
- return dummy->val == 1 ? dummy : dummy->next;
+ return dummy->val ? dummy : dummy->next;
}
};
```
@@ -178,10 +177,8 @@ func plusOne(head *ListNode) *ListNode {
head = head.Next
}
target.Val++
- target = target.Next
- for target != nil {
+ for target = target.Next; target != nil; target = target.Next {
target.Val = 0
- target = target.Next
}
if dummy.Val == 1 {
return dummy
@@ -190,6 +187,38 @@ func plusOne(head *ListNode) *ListNode {
}
```
+#### TypeScript
+
+```ts
+/**
+ * Definition for singly-linked list.
+ * class ListNode {
+ * val: number
+ * next: ListNode | null
+ * constructor(val?: number, next?: ListNode | null) {
+ * this.val = (val===undefined ? 0 : val)
+ * this.next = (next===undefined ? null : next)
+ * }
+ * }
+ */
+
+function plusOne(head: ListNode | null): ListNode | null {
+ const dummy = new ListNode(0, head);
+ let target = dummy;
+ while (head) {
+ if (head.val !== 9) {
+ target = head;
+ }
+ head = head.next;
+ }
+ target.val++;
+ for (target = target.next; target; target = target.next) {
+ target.val = 0;
+ }
+ return dummy.val ? dummy : dummy.next;
+}
+```
+
diff --git a/solution/0300-0399/0369.Plus One Linked List/README_EN.md b/solution/0300-0399/0369.Plus One Linked List/README_EN.md
index e56316d0e35b6..f34920e3a5e8a 100644
--- a/solution/0300-0399/0369.Plus One Linked List/README_EN.md
+++ b/solution/0300-0399/0369.Plus One Linked List/README_EN.md
@@ -44,7 +44,15 @@ tags:
-### Solution 1
+### Solution 1: Linked List Traversal
+
+We first set a dummy head node $\textit{dummy}$, initially with a value of $0$, and the successor node of $\textit{dummy}$ is the linked list $\textit{head}$.
+
+Next, we traverse the linked list starting from the dummy head node, find the last node that is not $9$, increment its value by $1$, and set the values of all nodes after this node to $0$.
+
+Finally, we check if the value of the dummy head node is $1$. If it is $1$, we return $\textit{dummy}$; otherwise, we return the successor node of $\textit{dummy}$.
+
+The time complexity is $O(n)$, where $n$ is the length of the linked list. The space complexity is $O(1)$.
@@ -57,7 +65,7 @@ tags:
# self.val = val
# self.next = next
class Solution:
- def plusOne(self, head: ListNode) -> ListNode:
+ def plusOne(self, head: Optional[ListNode]) -> Optional[ListNode]:
dummy = ListNode(0, head)
target = dummy
while head:
@@ -124,17 +132,16 @@ public:
ListNode* plusOne(ListNode* head) {
ListNode* dummy = new ListNode(0, head);
ListNode* target = dummy;
- while (head) {
- if (head->val != 9) target = head;
- head = head->next;
+ for (; head; head = head->next) {
+ if (head->val != 9) {
+ target = head;
+ }
}
- ++target->val;
- target = target->next;
- while (target) {
+ target->val++;
+ for (target = target->next; target; target = target->next) {
target->val = 0;
- target = target->next;
}
- return dummy->val == 1 ? dummy : dummy->next;
+ return dummy->val ? dummy : dummy->next;
}
};
```
@@ -159,10 +166,8 @@ func plusOne(head *ListNode) *ListNode {
head = head.Next
}
target.Val++
- target = target.Next
- for target != nil {
+ for target = target.Next; target != nil; target = target.Next {
target.Val = 0
- target = target.Next
}
if dummy.Val == 1 {
return dummy
@@ -171,6 +176,38 @@ func plusOne(head *ListNode) *ListNode {
}
```
+#### TypeScript
+
+```ts
+/**
+ * Definition for singly-linked list.
+ * class ListNode {
+ * val: number
+ * next: ListNode | null
+ * constructor(val?: number, next?: ListNode | null) {
+ * this.val = (val===undefined ? 0 : val)
+ * this.next = (next===undefined ? null : next)
+ * }
+ * }
+ */
+
+function plusOne(head: ListNode | null): ListNode | null {
+ const dummy = new ListNode(0, head);
+ let target = dummy;
+ while (head) {
+ if (head.val !== 9) {
+ target = head;
+ }
+ head = head.next;
+ }
+ target.val++;
+ for (target = target.next; target; target = target.next) {
+ target.val = 0;
+ }
+ return dummy.val ? dummy : dummy.next;
+}
+```
+
diff --git a/solution/0300-0399/0369.Plus One Linked List/Solution.cpp b/solution/0300-0399/0369.Plus One Linked List/Solution.cpp
index d608df47aa497..4039ca6ce9ba2 100644
--- a/solution/0300-0399/0369.Plus One Linked List/Solution.cpp
+++ b/solution/0300-0399/0369.Plus One Linked List/Solution.cpp
@@ -13,16 +13,15 @@ class Solution {
ListNode* plusOne(ListNode* head) {
ListNode* dummy = new ListNode(0, head);
ListNode* target = dummy;
- while (head) {
- if (head->val != 9) target = head;
- head = head->next;
+ for (; head; head = head->next) {
+ if (head->val != 9) {
+ target = head;
+ }
}
- ++target->val;
- target = target->next;
- while (target) {
+ target->val++;
+ for (target = target->next; target; target = target->next) {
target->val = 0;
- target = target->next;
}
- return dummy->val == 1 ? dummy : dummy->next;
+ return dummy->val ? dummy : dummy->next;
}
};
\ No newline at end of file
diff --git a/solution/0300-0399/0369.Plus One Linked List/Solution.go b/solution/0300-0399/0369.Plus One Linked List/Solution.go
index 2cc181b636ae9..e391dafc75f0b 100644
--- a/solution/0300-0399/0369.Plus One Linked List/Solution.go
+++ b/solution/0300-0399/0369.Plus One Linked List/Solution.go
@@ -15,10 +15,8 @@ func plusOne(head *ListNode) *ListNode {
head = head.Next
}
target.Val++
- target = target.Next
- for target != nil {
+ for target = target.Next; target != nil; target = target.Next {
target.Val = 0
- target = target.Next
}
if dummy.Val == 1 {
return dummy
diff --git a/solution/0300-0399/0369.Plus One Linked List/Solution.py b/solution/0300-0399/0369.Plus One Linked List/Solution.py
index 39f094896af21..ee84db74fc160 100644
--- a/solution/0300-0399/0369.Plus One Linked List/Solution.py
+++ b/solution/0300-0399/0369.Plus One Linked List/Solution.py
@@ -4,7 +4,7 @@
# self.val = val
# self.next = next
class Solution:
- def plusOne(self, head: ListNode) -> ListNode:
+ def plusOne(self, head: Optional[ListNode]) -> Optional[ListNode]:
dummy = ListNode(0, head)
target = dummy
while head:
diff --git a/solution/0300-0399/0369.Plus One Linked List/Solution.ts b/solution/0300-0399/0369.Plus One Linked List/Solution.ts
new file mode 100644
index 0000000000000..81a3c64edb53c
--- /dev/null
+++ b/solution/0300-0399/0369.Plus One Linked List/Solution.ts
@@ -0,0 +1,27 @@
+/**
+ * Definition for singly-linked list.
+ * class ListNode {
+ * val: number
+ * next: ListNode | null
+ * constructor(val?: number, next?: ListNode | null) {
+ * this.val = (val===undefined ? 0 : val)
+ * this.next = (next===undefined ? null : next)
+ * }
+ * }
+ */
+
+function plusOne(head: ListNode | null): ListNode | null {
+ const dummy = new ListNode(0, head);
+ let target = dummy;
+ while (head) {
+ if (head.val !== 9) {
+ target = head;
+ }
+ head = head.next;
+ }
+ target.val++;
+ for (target = target.next; target; target = target.next) {
+ target.val = 0;
+ }
+ return dummy.val ? dummy : dummy.next;
+}
diff --git a/solution/0300-0399/0387.First Unique Character in a String/README.md b/solution/0300-0399/0387.First Unique Character in a String/README.md
index eb945630e5bfe..146df01e483fd 100644
--- a/solution/0300-0399/0387.First Unique Character in a String/README.md
+++ b/solution/0300-0399/0387.First Unique Character in a String/README.md
@@ -59,15 +59,13 @@ tags:
-### 方法一:数组或哈希表
+### 方法一:计数
-我们可以用数组或哈希表 $cnt$ 记录字符串 $s$ 中每个字符出现的次数。
+我们用一个哈希表或者一个长度为 $26$ 的数组 $\text{cnt}$ 来存储每个字符出现的次数,然后从头开始遍历每个字符 $\text{s[i]}$,如果 $\text{cnt[s[i]]}$ 为 $1$,则返回 $i$。
-然后我们再遍历字符串 $s$,当遍历到某个字符 $c$ 时,如果 $cnt[c]=1$,则说明 $c$ 是第一个不重复的字符,返回它的索引即可。
+遍历结束后,如果没有找到符合条件的字符,返回 $-1$。
-如果遍历完字符串 $s$ 仍然没有找到不重复的字符,返回 $-1$。
-
-时间复杂度 $O(n)$,空间复杂度 $O(\Sigma)$,其中 $\Sigma$ 是字符集的大小。
+时间复杂度 $O(n)$,其中 $n$ 是字符串的长度。空间复杂度 $O(|\Sigma|)$,其中 $\Sigma$ 是字符集,本题中字符集为小写字母,所以 $|\Sigma|=26$。
@@ -145,12 +143,12 @@ func firstUniqChar(s string) int {
```ts
function firstUniqChar(s: string): number {
- const cnt = new Array(26).fill(0);
+ const cnt = new Map();
for (const c of s) {
- cnt[c.charCodeAt(0) - 97]++;
+ cnt.set(c, (cnt.get(c) || 0) + 1);
}
- for (let i = 0; i < s.length; i++) {
- if (cnt[s.charCodeAt(i) - 97] === 1) {
+ for (let i = 0; i < s.length; ++i) {
+ if (cnt.get(s[i]) === 1) {
return i;
}
}
@@ -166,12 +164,12 @@ function firstUniqChar(s: string): number {
* @return {number}
*/
var firstUniqChar = function (s) {
- const cnt = new Array(26).fill(0);
+ const cnt = new Map();
for (const c of s) {
- ++cnt[c.charCodeAt() - 'a'.charCodeAt()];
+ cnt.set(c, (cnt.get(c) || 0) + 1);
}
for (let i = 0; i < s.length; ++i) {
- if (cnt[s[i].charCodeAt() - 'a'.charCodeAt()] === 1) {
+ if (cnt.get(s[i]) === 1) {
return i;
}
}
diff --git a/solution/0300-0399/0387.First Unique Character in a String/README_EN.md b/solution/0300-0399/0387.First Unique Character in a String/README_EN.md
index a86551f835c7c..a063045a0d345 100644
--- a/solution/0300-0399/0387.First Unique Character in a String/README_EN.md
+++ b/solution/0300-0399/0387.First Unique Character in a String/README_EN.md
@@ -64,7 +64,13 @@ tags:
-### Solution 1
+### Solution 1: Counting
+
+We use a hash table or an array of length $26$ $\text{cnt}$ to store the frequency of each character. Then, we traverse each character $\text{s[i]}$ from the beginning. If $\text{cnt[s[i]]}$ is $1$, we return $i$.
+
+If no such character is found after the traversal, we return $-1$.
+
+The time complexity is $O(n)$, where $n$ is the length of the string. The space complexity is $O(|\Sigma|)$, where $\Sigma$ is the character set. In this problem, the character set consists of lowercase letters, so $|\Sigma|=26$.
@@ -142,12 +148,12 @@ func firstUniqChar(s string) int {
```ts
function firstUniqChar(s: string): number {
- const cnt = new Array(26).fill(0);
+ const cnt = new Map();
for (const c of s) {
- cnt[c.charCodeAt(0) - 97]++;
+ cnt.set(c, (cnt.get(c) || 0) + 1);
}
- for (let i = 0; i < s.length; i++) {
- if (cnt[s.charCodeAt(i) - 97] === 1) {
+ for (let i = 0; i < s.length; ++i) {
+ if (cnt.get(s[i]) === 1) {
return i;
}
}
@@ -163,12 +169,12 @@ function firstUniqChar(s: string): number {
* @return {number}
*/
var firstUniqChar = function (s) {
- const cnt = new Array(26).fill(0);
+ const cnt = new Map();
for (const c of s) {
- ++cnt[c.charCodeAt() - 'a'.charCodeAt()];
+ cnt.set(c, (cnt.get(c) || 0) + 1);
}
for (let i = 0; i < s.length; ++i) {
- if (cnt[s[i].charCodeAt() - 'a'.charCodeAt()] === 1) {
+ if (cnt.get(s[i]) === 1) {
return i;
}
}
diff --git a/solution/0300-0399/0387.First Unique Character in a String/Solution.js b/solution/0300-0399/0387.First Unique Character in a String/Solution.js
index 9e12bbbdd828e..5ffe59f022aa8 100644
--- a/solution/0300-0399/0387.First Unique Character in a String/Solution.js
+++ b/solution/0300-0399/0387.First Unique Character in a String/Solution.js
@@ -3,12 +3,12 @@
* @return {number}
*/
var firstUniqChar = function (s) {
- const cnt = new Array(26).fill(0);
+ const cnt = new Map();
for (const c of s) {
- ++cnt[c.charCodeAt() - 'a'.charCodeAt()];
+ cnt.set(c, (cnt.get(c) || 0) + 1);
}
for (let i = 0; i < s.length; ++i) {
- if (cnt[s[i].charCodeAt() - 'a'.charCodeAt()] === 1) {
+ if (cnt.get(s[i]) === 1) {
return i;
}
}
diff --git a/solution/0300-0399/0387.First Unique Character in a String/Solution.ts b/solution/0300-0399/0387.First Unique Character in a String/Solution.ts
index 78be86adcfab1..8fb60cff78022 100644
--- a/solution/0300-0399/0387.First Unique Character in a String/Solution.ts
+++ b/solution/0300-0399/0387.First Unique Character in a String/Solution.ts
@@ -1,10 +1,10 @@
function firstUniqChar(s: string): number {
- const cnt = new Array(26).fill(0);
+ const cnt = new Map();
for (const c of s) {
- cnt[c.charCodeAt(0) - 97]++;
+ cnt.set(c, (cnt.get(c) || 0) + 1);
}
- for (let i = 0; i < s.length; i++) {
- if (cnt[s.charCodeAt(i) - 97] === 1) {
+ for (let i = 0; i < s.length; ++i) {
+ if (cnt.get(s[i]) === 1) {
return i;
}
}
diff --git a/solution/0300-0399/0391.Perfect Rectangle/README.md b/solution/0300-0399/0391.Perfect Rectangle/README.md
index 0292de82c3f31..aee93688ddf51 100644
--- a/solution/0300-0399/0391.Perfect Rectangle/README.md
+++ b/solution/0300-0399/0391.Perfect Rectangle/README.md
@@ -3,7 +3,10 @@ comments: true
difficulty: 困难
edit_url: https://github.com/doocs/leetcode/edit/main/solution/0300-0399/0391.Perfect%20Rectangle/README.md
tags:
+ - 几何
- 数组
+ - 哈希表
+ - 数学
- 扫描线
---
diff --git a/solution/0300-0399/0391.Perfect Rectangle/README_EN.md b/solution/0300-0399/0391.Perfect Rectangle/README_EN.md
index 6c770c7548d75..7fc5040dfe3c2 100644
--- a/solution/0300-0399/0391.Perfect Rectangle/README_EN.md
+++ b/solution/0300-0399/0391.Perfect Rectangle/README_EN.md
@@ -3,7 +3,10 @@ comments: true
difficulty: Hard
edit_url: https://github.com/doocs/leetcode/edit/main/solution/0300-0399/0391.Perfect%20Rectangle/README_EN.md
tags:
+ - Geometry
- Array
+ - Hash Table
+ - Math
- Line Sweep
---
diff --git a/solution/0300-0399/0394.Decode String/README.md b/solution/0300-0399/0394.Decode String/README.md
index 0cbd5f13b03b2..7d1e91b5d87c6 100644
--- a/solution/0300-0399/0394.Decode String/README.md
+++ b/solution/0300-0399/0394.Decode String/README.md
@@ -26,6 +26,8 @@ tags:
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。
+
测试用例保证输出的长度不会超过 105。
+
示例 1:
diff --git a/solution/0400-0499/0405.Convert a Number to Hexadecimal/README.md b/solution/0400-0499/0405.Convert a Number to Hexadecimal/README.md
index c7938f4dbc6e9..02ff376c891b7 100644
--- a/solution/0400-0499/0405.Convert a Number to Hexadecimal/README.md
+++ b/solution/0400-0499/0405.Convert a Number to Hexadecimal/README.md
@@ -5,6 +5,7 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/0400-0499/0405.Co
tags:
- 位运算
- 数学
+ - 字符串
---
diff --git a/solution/0400-0499/0405.Convert a Number to Hexadecimal/README_EN.md b/solution/0400-0499/0405.Convert a Number to Hexadecimal/README_EN.md
index d47e566ca8a25..97a155f1808e6 100644
--- a/solution/0400-0499/0405.Convert a Number to Hexadecimal/README_EN.md
+++ b/solution/0400-0499/0405.Convert a Number to Hexadecimal/README_EN.md
@@ -5,6 +5,7 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/0400-0499/0405.Co
tags:
- Bit Manipulation
- Math
+ - String
---
diff --git a/solution/0400-0499/0412.Fizz Buzz/README.md b/solution/0400-0499/0412.Fizz Buzz/README.md
index e700c0a3089e9..19d4d3abe8a6c 100644
--- a/solution/0400-0499/0412.Fizz Buzz/README.md
+++ b/solution/0400-0499/0412.Fizz Buzz/README.md
@@ -18,7 +18,7 @@ tags:
-
给你一个整数 n ,找出从 1 到 n 各个整数的 Fizz Buzz 表示,并用字符串数组 answer(下标从 1 开始)返回结果,其中:
+
给你一个整数 n ,返回一个字符串数组 answer(下标从 1 开始),其中:
answer[i] == "FizzBuzz" 如果 i 同时是 3 和 5 的倍数。
diff --git a/solution/0400-0499/0416.Partition Equal Subset Sum/README.md b/solution/0400-0499/0416.Partition Equal Subset Sum/README.md
index fd4551f364ff0..b31c4b54d636d 100644
--- a/solution/0400-0499/0416.Partition Equal Subset Sum/README.md
+++ b/solution/0400-0499/0416.Partition Equal Subset Sum/README.md
@@ -193,36 +193,24 @@ function canPartition(nums: number[]): boolean {
```rust
impl Solution {
- #[allow(dead_code)]
pub fn can_partition(nums: Vec) -> bool {
- let mut sum = 0;
- for e in &nums {
- sum += *e;
- }
-
- if sum % 2 != 0 {
+ let s: i32 = nums.iter().sum();
+ if s % 2 != 0 {
return false;
}
-
+ let m = (s / 2) as usize;
let n = nums.len();
- let m = (sum / 2) as usize;
- let mut dp: Vec> = vec![vec![false; m + 1]; n + 1];
-
- // Initialize the dp vector
- dp[0][0] = true;
+ let mut f = vec![vec![false; m + 1]; n + 1];
+ f[0][0] = true;
- // Begin the actual dp process
for i in 1..=n {
+ let x = nums[i - 1] as usize;
for j in 0..=m {
- dp[i][j] = if (nums[i - 1] as usize) > j {
- dp[i - 1][j]
- } else {
- dp[i - 1][j] || dp[i - 1][j - (nums[i - 1] as usize)]
- };
+ f[i][j] = f[i - 1][j] || (j >= x && f[i - 1][j - x]);
}
}
- dp[n][m]
+ f[n][m]
}
}
```
@@ -379,36 +367,23 @@ function canPartition(nums: number[]): boolean {
```rust
impl Solution {
- #[allow(dead_code)]
pub fn can_partition(nums: Vec) -> bool {
- let mut sum = 0;
- for e in &nums {
- sum += *e;
- }
-
- if sum % 2 != 0 {
+ let s: i32 = nums.iter().sum();
+ if s % 2 != 0 {
return false;
}
+ let m = (s / 2) as usize;
+ let mut f = vec![false; m + 1];
+ f[0] = true;
- let m = (sum >> 1) as usize;
-
- // Here dp[i] means if it can be sum up to `i` for all the number we've traversed through so far
- // Which is actually compressing the 2-D dp vector to 1-D
- let mut dp: Vec = vec![false; m + 1];
-
- // Initialize the dp vector
- dp[0] = true;
-
- // Begin the actual dp process
- for e in &nums {
- // For every num in nums vector
- for i in (*e as usize..=m).rev() {
- // Update the current status
- dp[i] |= dp[i - (*e as usize)];
+ for x in nums {
+ let x = x as usize;
+ for j in (x..=m).rev() {
+ f[j] = f[j] || f[j - x];
}
}
- dp[m]
+ f[m]
}
}
```
diff --git a/solution/0400-0499/0416.Partition Equal Subset Sum/README_EN.md b/solution/0400-0499/0416.Partition Equal Subset Sum/README_EN.md
index 1b1a01a59566d..ad13f92581249 100644
--- a/solution/0400-0499/0416.Partition Equal Subset Sum/README_EN.md
+++ b/solution/0400-0499/0416.Partition Equal Subset Sum/README_EN.md
@@ -192,36 +192,24 @@ function canPartition(nums: number[]): boolean {
```rust
impl Solution {
- #[allow(dead_code)]
pub fn can_partition(nums: Vec) -> bool {
- let mut sum = 0;
- for e in &nums {
- sum += *e;
- }
-
- if sum % 2 != 0 {
+ let s: i32 = nums.iter().sum();
+ if s % 2 != 0 {
return false;
}
-
+ let m = (s / 2) as usize;
let n = nums.len();
- let m = (sum / 2) as usize;
- let mut dp: Vec> = vec![vec![false; m + 1]; n + 1];
-
- // Initialize the dp vector
- dp[0][0] = true;
+ let mut f = vec![vec![false; m + 1]; n + 1];
+ f[0][0] = true;
- // Begin the actual dp process
for i in 1..=n {
+ let x = nums[i - 1] as usize;
for j in 0..=m {
- dp[i][j] = if (nums[i - 1] as usize) > j {
- dp[i - 1][j]
- } else {
- dp[i - 1][j] || dp[i - 1][j - (nums[i - 1] as usize)]
- };
+ f[i][j] = f[i - 1][j] || (j >= x && f[i - 1][j - x]);
}
}
- dp[n][m]
+ f[n][m]
}
}
```
@@ -378,36 +366,23 @@ function canPartition(nums: number[]): boolean {
```rust
impl Solution {
- #[allow(dead_code)]
pub fn can_partition(nums: Vec) -> bool {
- let mut sum = 0;
- for e in &nums {
- sum += *e;
- }
-
- if sum % 2 != 0 {
+ let s: i32 = nums.iter().sum();
+ if s % 2 != 0 {
return false;
}
+ let m = (s / 2) as usize;
+ let mut f = vec![false; m + 1];
+ f[0] = true;
- let m = (sum >> 1) as usize;
-
- // Here dp[i] means if it can be sum up to `i` for all the number we've traversed through so far
- // Which is actually compressing the 2-D dp vector to 1-D
- let mut dp: Vec = vec![false; m + 1];
-
- // Initialize the dp vector
- dp[0] = true;
-
- // Begin the actual dp process
- for e in &nums {
- // For every num in nums vector
- for i in (*e as usize..=m).rev() {
- // Update the current status
- dp[i] |= dp[i - (*e as usize)];
+ for x in nums {
+ let x = x as usize;
+ for j in (x..=m).rev() {
+ f[j] = f[j] || f[j - x];
}
}
- dp[m]
+ f[m]
}
}
```
diff --git a/solution/0400-0499/0416.Partition Equal Subset Sum/Solution.rs b/solution/0400-0499/0416.Partition Equal Subset Sum/Solution.rs
index 498f8f59c63ab..1d4cdd5f8fbcb 100644
--- a/solution/0400-0499/0416.Partition Equal Subset Sum/Solution.rs
+++ b/solution/0400-0499/0416.Partition Equal Subset Sum/Solution.rs
@@ -1,33 +1,21 @@
impl Solution {
- #[allow(dead_code)]
pub fn can_partition(nums: Vec) -> bool {
- let mut sum = 0;
- for e in &nums {
- sum += *e;
- }
-
- if sum % 2 != 0 {
+ let s: i32 = nums.iter().sum();
+ if s % 2 != 0 {
return false;
}
-
+ let m = (s / 2) as usize;
let n = nums.len();
- let m = (sum / 2) as usize;
- let mut dp: Vec> = vec![vec![false; m + 1]; n + 1];
-
- // Initialize the dp vector
- dp[0][0] = true;
+ let mut f = vec![vec![false; m + 1]; n + 1];
+ f[0][0] = true;
- // Begin the actual dp process
for i in 1..=n {
+ let x = nums[i - 1] as usize;
for j in 0..=m {
- dp[i][j] = if (nums[i - 1] as usize) > j {
- dp[i - 1][j]
- } else {
- dp[i - 1][j] || dp[i - 1][j - (nums[i - 1] as usize)]
- };
+ f[i][j] = f[i - 1][j] || (j >= x && f[i - 1][j - x]);
}
}
- dp[n][m]
+ f[n][m]
}
}
diff --git a/solution/0400-0499/0416.Partition Equal Subset Sum/Solution2.rs b/solution/0400-0499/0416.Partition Equal Subset Sum/Solution2.rs
index b5e1dfb2d9357..a3bacdf80387c 100644
--- a/solution/0400-0499/0416.Partition Equal Subset Sum/Solution2.rs
+++ b/solution/0400-0499/0416.Partition Equal Subset Sum/Solution2.rs
@@ -1,33 +1,20 @@
impl Solution {
- #[allow(dead_code)]
pub fn can_partition(nums: Vec) -> bool {
- let mut sum = 0;
- for e in &nums {
- sum += *e;
- }
-
- if sum % 2 != 0 {
+ let s: i32 = nums.iter().sum();
+ if s % 2 != 0 {
return false;
}
+ let m = (s / 2) as usize;
+ let mut f = vec![false; m + 1];
+ f[0] = true;
- let m = (sum >> 1) as usize;
-
- // Here dp[i] means if it can be sum up to `i` for all the number we've traversed through so far
- // Which is actually compressing the 2-D dp vector to 1-D
- let mut dp: Vec = vec![false; m + 1];
-
- // Initialize the dp vector
- dp[0] = true;
-
- // Begin the actual dp process
- for e in &nums {
- // For every num in nums vector
- for i in (*e as usize..=m).rev() {
- // Update the current status
- dp[i] |= dp[i - (*e as usize)];
+ for x in nums {
+ let x = x as usize;
+ for j in (x..=m).rev() {
+ f[j] = f[j] || f[j - x];
}
}
- dp[m]
+ f[m]
}
}
diff --git a/solution/0400-0499/0418.Sentence Screen Fitting/README.md b/solution/0400-0499/0418.Sentence Screen Fitting/README.md
index 98249f3e78e13..f11e4f1413eeb 100644
--- a/solution/0400-0499/0418.Sentence Screen Fitting/README.md
+++ b/solution/0400-0499/0418.Sentence Screen Fitting/README.md
@@ -54,12 +54,12 @@ bcd-e-
diff --git a/solution/0400-0499/0434.Number of Segments in a String/README.md b/solution/0400-0499/0434.Number of Segments in a String/README.md
index bb68680de4334..97b8cf15f9b26 100644
--- a/solution/0400-0499/0434.Number of Segments in a String/README.md
+++ b/solution/0400-0499/0434.Number of Segments in a String/README.md
@@ -35,9 +35,9 @@ tags:
### 方法一:字符串分割
-将字符串 `s` 按照空格进行分割,然后统计不为空的单词个数。
+我们将字符串 $\textit{s}$ 按照空格进行分割,然后统计不为空的单词个数。
-时间复杂度 $O(n)$,空间复杂度 $O(n)$。
+时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串 $\textit{s}$ 的长度。
@@ -93,6 +93,14 @@ func countSegments(s string) int {
}
```
+#### TypeScript
+
+```ts
+function countSegments(s: string): number {
+ return s.split(/\s+/).filter(Boolean).length;
+}
+```
+
#### PHP
```php
@@ -122,9 +130,11 @@ class Solution {
### 方法二:模拟
-直接模拟,遍历字符串,检测每个字符,统计个数。
+我们也可以直接遍历字符串的每个字符 $\text{s[i]}$,如果 $\text{s[i]}$ 不是空格且 $\text{s[i-1]}$ 是空格或者 $i = 0$,那么就说明 $\text{s[i]}$ 是一个新的单词的开始,我们就将答案加一。
-时间复杂度 $O(n)$,空间复杂度 $O(1)$。
+遍历结束后,返回答案即可。
+
+时间复杂度 $O(n)$,其中 $n$ 为字符串 $\textit{s}$ 的长度。空间复杂度 $O(1)$。
@@ -187,6 +197,43 @@ func countSegments(s string) int {
}
```
+#### TypeScript
+
+```ts
+function countSegments(s: string): number {
+ let ans = 0;
+ for (let i = 0; i < s.length; i++) {
+ let c = s[i];
+ if (c !== ' ' && (i === 0 || s[i - 1] === ' ')) {
+ ans++;
+ }
+ }
+ return ans;
+}
+```
+
+#### PHP
+
+```php
+class Solution {
+ /**
+ * @param String $s
+ * @return Integer
+ */
+ function countSegments($s) {
+ $ans = 0;
+ $n = strlen($s);
+ for ($i = 0; $i < $n; $i++) {
+ $c = $s[$i];
+ if ($c !== ' ' && ($i === 0 || $s[$i - 1] === ' ')) {
+ $ans++;
+ }
+ }
+ return $ans;
+ }
+}
+```
+
diff --git a/solution/0400-0499/0434.Number of Segments in a String/README_EN.md b/solution/0400-0499/0434.Number of Segments in a String/README_EN.md
index becc602f25288..de310aced515b 100644
--- a/solution/0400-0499/0434.Number of Segments in a String/README_EN.md
+++ b/solution/0400-0499/0434.Number of Segments in a String/README_EN.md
@@ -51,7 +51,11 @@ tags:
-### Solution 1
+### Solution 1: String Splitting
+
+We split the string $\textit{s}$ by spaces and then count the number of non-empty words.
+
+The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the string $\textit{s}$.
@@ -107,6 +111,14 @@ func countSegments(s string) int {
}
```
+#### TypeScript
+
+```ts
+function countSegments(s: string): number {
+ return s.split(/\s+/).filter(Boolean).length;
+}
+```
+
#### PHP
```php
@@ -134,7 +146,13 @@ class Solution {
-### Solution 2
+### Solution 2: Simulation
+
+We can also directly traverse each character $\text{s[i]}$ in the string. If $\text{s[i]}$ is not a space and $\text{s[i-1]}$ is a space or $i = 0$, then $\text{s[i]}$ marks the beginning of a new word, and we increment the answer by one.
+
+After the traversal, we return the answer.
+
+The time complexity is $O(n)$, where $n$ is the length of the string $\textit{s}$. The space complexity is $O(1)$.
@@ -197,6 +215,43 @@ func countSegments(s string) int {
}
```
+#### TypeScript
+
+```ts
+function countSegments(s: string): number {
+ let ans = 0;
+ for (let i = 0; i < s.length; i++) {
+ let c = s[i];
+ if (c !== ' ' && (i === 0 || s[i - 1] === ' ')) {
+ ans++;
+ }
+ }
+ return ans;
+}
+```
+
+#### PHP
+
+```php
+class Solution {
+ /**
+ * @param String $s
+ * @return Integer
+ */
+ function countSegments($s) {
+ $ans = 0;
+ $n = strlen($s);
+ for ($i = 0; $i < $n; $i++) {
+ $c = $s[$i];
+ if ($c !== ' ' && ($i === 0 || $s[$i - 1] === ' ')) {
+ $ans++;
+ }
+ }
+ return $ans;
+ }
+}
+```
+
diff --git a/solution/0400-0499/0434.Number of Segments in a String/Solution.ts b/solution/0400-0499/0434.Number of Segments in a String/Solution.ts
new file mode 100644
index 0000000000000..e31e039bb1416
--- /dev/null
+++ b/solution/0400-0499/0434.Number of Segments in a String/Solution.ts
@@ -0,0 +1,3 @@
+function countSegments(s: string): number {
+ return s.split(/\s+/).filter(Boolean).length;
+}
diff --git a/solution/0400-0499/0434.Number of Segments in a String/Solution2.php b/solution/0400-0499/0434.Number of Segments in a String/Solution2.php
new file mode 100644
index 0000000000000..70de51e4e781f
--- /dev/null
+++ b/solution/0400-0499/0434.Number of Segments in a String/Solution2.php
@@ -0,0 +1,17 @@
+class Solution {
+ /**
+ * @param String $s
+ * @return Integer
+ */
+ function countSegments($s) {
+ $ans = 0;
+ $n = strlen($s);
+ for ($i = 0; $i < $n; $i++) {
+ $c = $s[$i];
+ if ($c !== ' ' && ($i === 0 || $s[$i - 1] === ' ')) {
+ $ans++;
+ }
+ }
+ return $ans;
+ }
+}
\ No newline at end of file
diff --git a/solution/0400-0499/0434.Number of Segments in a String/Solution2.ts b/solution/0400-0499/0434.Number of Segments in a String/Solution2.ts
new file mode 100644
index 0000000000000..27613c80065e9
--- /dev/null
+++ b/solution/0400-0499/0434.Number of Segments in a String/Solution2.ts
@@ -0,0 +1,10 @@
+function countSegments(s: string): number {
+ let ans = 0;
+ for (let i = 0; i < s.length; i++) {
+ let c = s[i];
+ if (c !== ' ' && (i === 0 || s[i - 1] === ' ')) {
+ ans++;
+ }
+ }
+ return ans;
+}
diff --git a/solution/0400-0499/0435.Non-overlapping Intervals/README.md b/solution/0400-0499/0435.Non-overlapping Intervals/README.md
index d11d9c230875c..239271f1d1323 100644
--- a/solution/0400-0499/0435.Non-overlapping Intervals/README.md
+++ b/solution/0400-0499/0435.Non-overlapping Intervals/README.md
@@ -65,9 +65,18 @@ tags:
-### 方法一:转换为最长上升子序列问题
+### 方法一:排序 + 贪心
-最长上升子序列问题,动态规划的做法,时间复杂度是 $O(n^2)$,这里可以采用贪心优化,将复杂度降至 $O(n\log n)$。
+我们首先将区间按照右边界升序排序,用一个变量 $\textit{pre}$ 记录上一个区间的右边界,用一个变量 $\textit{ans}$ 记录需要移除的区间数量,初始时 $\textit{ans} = \textit{intervals.length}$。
+
+然后遍历区间,对于每一个区间:
+
+- 若当前区间的左边界大于等于 $\textit{pre}$,说明该区间无需移除,直接更新 $\textit{pre}$ 为当前区间的右边界,然后将 $\textit{ans}$ 减一;
+- 否则,说明该区间需要移除,不需要更新 $\textit{pre}$ 和 $\textit{ans}$。
+
+最后返回 $\textit{ans}$ 即可。
+
+时间复杂度 $O(n \times \log n)$,空间复杂度 $O(\log n)$。其中 $n$ 为区间的数量。
@@ -77,12 +86,12 @@ tags:
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
intervals.sort(key=lambda x: x[1])
- ans, t = 0, intervals[0][1]
- for s, e in intervals[1:]:
- if s >= t:
- t = e
- else:
- ans += 1
+ ans = len(intervals)
+ pre = -inf
+ for l, r in intervals:
+ if pre <= l:
+ ans -= 1
+ pre = r
return ans
```
@@ -91,13 +100,14 @@ class Solution:
```java
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
- Arrays.sort(intervals, Comparator.comparingInt(a -> a[1]));
- int t = intervals[0][1], ans = 0;
- for (int i = 1; i < intervals.length; ++i) {
- if (intervals[i][0] >= t) {
- t = intervals[i][1];
- } else {
- ++ans;
+ Arrays.sort(intervals, (a, b) -> a[1] - b[1]);
+ int ans = intervals.length;
+ int pre = Integer.MIN_VALUE;
+ for (var e : intervals) {
+ int l = e[0], r = e[1];
+ if (pre <= l) {
+ --ans;
+ pre = r;
}
}
return ans;
@@ -111,13 +121,17 @@ class Solution {
class Solution {
public:
int eraseOverlapIntervals(vector>& intervals) {
- sort(intervals.begin(), intervals.end(), [](const auto& a, const auto& b) { return a[1] < b[1]; });
- int ans = 0, t = intervals[0][1];
- for (int i = 1; i < intervals.size(); ++i) {
- if (t <= intervals[i][0])
- t = intervals[i][1];
- else
- ++ans;
+ ranges::sort(intervals, [](const vector& a, const vector& b) {
+ return a[1] < b[1];
+ });
+ int ans = intervals.size();
+ int pre = INT_MIN;
+ for (const auto& e : intervals) {
+ int l = e[0], r = e[1];
+ if (pre <= l) {
+ --ans;
+ pre = r;
+ }
}
return ans;
}
@@ -131,12 +145,13 @@ func eraseOverlapIntervals(intervals [][]int) int {
sort.Slice(intervals, func(i, j int) bool {
return intervals[i][1] < intervals[j][1]
})
- t, ans := intervals[0][1], 0
- for i := 1; i < len(intervals); i++ {
- if intervals[i][0] >= t {
- t = intervals[i][1]
- } else {
- ans++
+ ans := len(intervals)
+ pre := math.MinInt32
+ for _, e := range intervals {
+ l, r := e[0], e[1]
+ if pre <= l {
+ ans--
+ pre = r
}
}
return ans
@@ -148,14 +163,11 @@ func eraseOverlapIntervals(intervals [][]int) int {
```ts
function eraseOverlapIntervals(intervals: number[][]): number {
intervals.sort((a, b) => a[1] - b[1]);
- let end = intervals[0][1],
- ans = 0;
- for (let i = 1; i < intervals.length; ++i) {
- let cur = intervals[i];
- if (end > cur[0]) {
- ans++;
- } else {
- end = cur[1];
+ let [ans, pre] = [intervals.length, -Infinity];
+ for (const [l, r] of intervals) {
+ if (pre <= l) {
+ --ans;
+ pre = r;
}
}
return ans;
@@ -166,76 +178,4 @@ function eraseOverlapIntervals(intervals: number[][]): number {
-
-
-### 方法二:排序 + 贪心
-
-先按照区间右边界排序。优先选择最小的区间的右边界作为起始边界。遍历区间:
-
-- 若当前区间左边界大于等于起始右边界,说明该区间无需移除,直接更新起始右边界;
-- 否则说明该区间需要移除,更新移除区间的数量 ans。
-
-最后返回 ans 即可。
-
-时间复杂度 $O(n\log n)$。
-
-
-
-#### Python3
-
-```python
-class Solution:
- def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
- intervals.sort()
- d = [intervals[0][1]]
- for s, e in intervals[1:]:
- if s >= d[-1]:
- d.append(e)
- else:
- idx = bisect_left(d, s)
- d[idx] = min(d[idx], e)
- return len(intervals) - len(d)
-```
-
-#### Java
-
-```java
-class Solution {
- public int eraseOverlapIntervals(int[][] intervals) {
- Arrays.sort(intervals, (a, b) -> {
- if (a[0] != b[0]) {
- return a[0] - b[0];
- }
- return a[1] - b[1];
- });
- int n = intervals.length;
- int[] d = new int[n + 1];
- d[1] = intervals[0][1];
- int size = 1;
- for (int i = 1; i < n; ++i) {
- int s = intervals[i][0], e = intervals[i][1];
- if (s >= d[size]) {
- d[++size] = e;
- } else {
- int left = 1, right = size;
- while (left < right) {
- int mid = (left + right) >> 1;
- if (d[mid] >= s) {
- right = mid;
- } else {
- left = mid + 1;
- }
- }
- d[left] = Math.min(d[left], e);
- }
- }
- return n - size;
- }
-}
-```
-
-
-
-
-
diff --git a/solution/0400-0499/0435.Non-overlapping Intervals/README_EN.md b/solution/0400-0499/0435.Non-overlapping Intervals/README_EN.md
index d4ea312a3852c..61a99a2fbd245 100644
--- a/solution/0400-0499/0435.Non-overlapping Intervals/README_EN.md
+++ b/solution/0400-0499/0435.Non-overlapping Intervals/README_EN.md
@@ -63,7 +63,18 @@ tags:
-### Solution 1
+### Solution 1: Sorting + Greedy
+
+We first sort the intervals in ascending order by their right boundary. We use a variable $\textit{pre}$ to record the right boundary of the previous interval and a variable $\textit{ans}$ to record the number of intervals that need to be removed. Initially, $\textit{ans} = \textit{intervals.length}$.
+
+Then we iterate through the intervals. For each interval:
+
+- If the left boundary of the current interval is greater than or equal to $\textit{pre}$, it means that this interval does not need to be removed. We directly update $\textit{pre}$ to the right boundary of the current interval and decrement $\textit{ans}$ by one;
+- Otherwise, it means that this interval needs to be removed, and we do not need to update $\textit{pre}$ and $\textit{ans}$.
+
+Finally, we return $\textit{ans}$.
+
+The time complexity is $O(n \times \log n)$, and the space complexity is $O(\log n)$, where $n$ is the number of intervals.
@@ -73,12 +84,12 @@ tags:
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
intervals.sort(key=lambda x: x[1])
- ans, t = 0, intervals[0][1]
- for s, e in intervals[1:]:
- if s >= t:
- t = e
- else:
- ans += 1
+ ans = len(intervals)
+ pre = -inf
+ for l, r in intervals:
+ if pre <= l:
+ ans -= 1
+ pre = r
return ans
```
@@ -87,13 +98,14 @@ class Solution:
```java
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
- Arrays.sort(intervals, Comparator.comparingInt(a -> a[1]));
- int t = intervals[0][1], ans = 0;
- for (int i = 1; i < intervals.length; ++i) {
- if (intervals[i][0] >= t) {
- t = intervals[i][1];
- } else {
- ++ans;
+ Arrays.sort(intervals, (a, b) -> a[1] - b[1]);
+ int ans = intervals.length;
+ int pre = Integer.MIN_VALUE;
+ for (var e : intervals) {
+ int l = e[0], r = e[1];
+ if (pre <= l) {
+ --ans;
+ pre = r;
}
}
return ans;
@@ -107,13 +119,17 @@ class Solution {
class Solution {
public:
int eraseOverlapIntervals(vector>& intervals) {
- sort(intervals.begin(), intervals.end(), [](const auto& a, const auto& b) { return a[1] < b[1]; });
- int ans = 0, t = intervals[0][1];
- for (int i = 1; i < intervals.size(); ++i) {
- if (t <= intervals[i][0])
- t = intervals[i][1];
- else
- ++ans;
+ ranges::sort(intervals, [](const vector& a, const vector& b) {
+ return a[1] < b[1];
+ });
+ int ans = intervals.size();
+ int pre = INT_MIN;
+ for (const auto& e : intervals) {
+ int l = e[0], r = e[1];
+ if (pre <= l) {
+ --ans;
+ pre = r;
+ }
}
return ans;
}
@@ -127,12 +143,13 @@ func eraseOverlapIntervals(intervals [][]int) int {
sort.Slice(intervals, func(i, j int) bool {
return intervals[i][1] < intervals[j][1]
})
- t, ans := intervals[0][1], 0
- for i := 1; i < len(intervals); i++ {
- if intervals[i][0] >= t {
- t = intervals[i][1]
- } else {
- ans++
+ ans := len(intervals)
+ pre := math.MinInt32
+ for _, e := range intervals {
+ l, r := e[0], e[1]
+ if pre <= l {
+ ans--
+ pre = r
}
}
return ans
@@ -144,14 +161,11 @@ func eraseOverlapIntervals(intervals [][]int) int {
```ts
function eraseOverlapIntervals(intervals: number[][]): number {
intervals.sort((a, b) => a[1] - b[1]);
- let end = intervals[0][1],
- ans = 0;
- for (let i = 1; i < intervals.length; ++i) {
- let cur = intervals[i];
- if (end > cur[0]) {
- ans++;
- } else {
- end = cur[1];
+ let [ans, pre] = [intervals.length, -Infinity];
+ for (const [l, r] of intervals) {
+ if (pre <= l) {
+ --ans;
+ pre = r;
}
}
return ans;
@@ -162,67 +176,4 @@ function eraseOverlapIntervals(intervals: number[][]): number {
-
-
-### Solution 2
-
-
-
-#### Python3
-
-```python
-class Solution:
- def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
- intervals.sort()
- d = [intervals[0][1]]
- for s, e in intervals[1:]:
- if s >= d[-1]:
- d.append(e)
- else:
- idx = bisect_left(d, s)
- d[idx] = min(d[idx], e)
- return len(intervals) - len(d)
-```
-
-#### Java
-
-```java
-class Solution {
- public int eraseOverlapIntervals(int[][] intervals) {
- Arrays.sort(intervals, (a, b) -> {
- if (a[0] != b[0]) {
- return a[0] - b[0];
- }
- return a[1] - b[1];
- });
- int n = intervals.length;
- int[] d = new int[n + 1];
- d[1] = intervals[0][1];
- int size = 1;
- for (int i = 1; i < n; ++i) {
- int s = intervals[i][0], e = intervals[i][1];
- if (s >= d[size]) {
- d[++size] = e;
- } else {
- int left = 1, right = size;
- while (left < right) {
- int mid = (left + right) >> 1;
- if (d[mid] >= s) {
- right = mid;
- } else {
- left = mid + 1;
- }
- }
- d[left] = Math.min(d[left], e);
- }
- }
- return n - size;
- }
-}
-```
-
-
-
-
-
diff --git a/solution/0400-0499/0435.Non-overlapping Intervals/Solution.cpp b/solution/0400-0499/0435.Non-overlapping Intervals/Solution.cpp
index e754f1db36a3a..f362aa4fee404 100644
--- a/solution/0400-0499/0435.Non-overlapping Intervals/Solution.cpp
+++ b/solution/0400-0499/0435.Non-overlapping Intervals/Solution.cpp
@@ -1,14 +1,18 @@
class Solution {
public:
int eraseOverlapIntervals(vector>& intervals) {
- sort(intervals.begin(), intervals.end(), [](const auto& a, const auto& b) { return a[1] < b[1]; });
- int ans = 0, t = intervals[0][1];
- for (int i = 1; i < intervals.size(); ++i) {
- if (t <= intervals[i][0])
- t = intervals[i][1];
- else
- ++ans;
+ ranges::sort(intervals, [](const vector& a, const vector& b) {
+ return a[1] < b[1];
+ });
+ int ans = intervals.size();
+ int pre = INT_MIN;
+ for (const auto& e : intervals) {
+ int l = e[0], r = e[1];
+ if (pre <= l) {
+ --ans;
+ pre = r;
+ }
}
return ans;
}
-};
\ No newline at end of file
+};
diff --git a/solution/0400-0499/0435.Non-overlapping Intervals/Solution.go b/solution/0400-0499/0435.Non-overlapping Intervals/Solution.go
index d40eb5b6378ed..16085cd32cfb7 100644
--- a/solution/0400-0499/0435.Non-overlapping Intervals/Solution.go
+++ b/solution/0400-0499/0435.Non-overlapping Intervals/Solution.go
@@ -2,13 +2,14 @@ func eraseOverlapIntervals(intervals [][]int) int {
sort.Slice(intervals, func(i, j int) bool {
return intervals[i][1] < intervals[j][1]
})
- t, ans := intervals[0][1], 0
- for i := 1; i < len(intervals); i++ {
- if intervals[i][0] >= t {
- t = intervals[i][1]
- } else {
- ans++
+ ans := len(intervals)
+ pre := math.MinInt32
+ for _, e := range intervals {
+ l, r := e[0], e[1]
+ if pre <= l {
+ ans--
+ pre = r
}
}
return ans
-}
\ No newline at end of file
+}
diff --git a/solution/0400-0499/0435.Non-overlapping Intervals/Solution.java b/solution/0400-0499/0435.Non-overlapping Intervals/Solution.java
index 06940f1be5f62..907073e547ef1 100644
--- a/solution/0400-0499/0435.Non-overlapping Intervals/Solution.java
+++ b/solution/0400-0499/0435.Non-overlapping Intervals/Solution.java
@@ -1,14 +1,15 @@
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
- Arrays.sort(intervals, Comparator.comparingInt(a -> a[1]));
- int t = intervals[0][1], ans = 0;
- for (int i = 1; i < intervals.length; ++i) {
- if (intervals[i][0] >= t) {
- t = intervals[i][1];
- } else {
- ++ans;
+ Arrays.sort(intervals, (a, b) -> a[1] - b[1]);
+ int ans = intervals.length;
+ int pre = Integer.MIN_VALUE;
+ for (var e : intervals) {
+ int l = e[0], r = e[1];
+ if (pre <= l) {
+ --ans;
+ pre = r;
}
}
return ans;
}
-}
\ No newline at end of file
+}
diff --git a/solution/0400-0499/0435.Non-overlapping Intervals/Solution.py b/solution/0400-0499/0435.Non-overlapping Intervals/Solution.py
index d599421163958..55d4b26112c33 100644
--- a/solution/0400-0499/0435.Non-overlapping Intervals/Solution.py
+++ b/solution/0400-0499/0435.Non-overlapping Intervals/Solution.py
@@ -1,10 +1,10 @@
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
intervals.sort(key=lambda x: x[1])
- ans, t = 0, intervals[0][1]
- for s, e in intervals[1:]:
- if s >= t:
- t = e
- else:
- ans += 1
+ ans = len(intervals)
+ pre = -inf
+ for l, r in intervals:
+ if pre <= l:
+ ans -= 1
+ pre = r
return ans
diff --git a/solution/0400-0499/0435.Non-overlapping Intervals/Solution.ts b/solution/0400-0499/0435.Non-overlapping Intervals/Solution.ts
index d10fa2a880de6..9e6ced4c9275e 100644
--- a/solution/0400-0499/0435.Non-overlapping Intervals/Solution.ts
+++ b/solution/0400-0499/0435.Non-overlapping Intervals/Solution.ts
@@ -1,13 +1,10 @@
function eraseOverlapIntervals(intervals: number[][]): number {
intervals.sort((a, b) => a[1] - b[1]);
- let end = intervals[0][1],
- ans = 0;
- for (let i = 1; i < intervals.length; ++i) {
- let cur = intervals[i];
- if (end > cur[0]) {
- ans++;
- } else {
- end = cur[1];
+ let [ans, pre] = [intervals.length, -Infinity];
+ for (const [l, r] of intervals) {
+ if (pre <= l) {
+ --ans;
+ pre = r;
}
}
return ans;
diff --git a/solution/0400-0499/0435.Non-overlapping Intervals/Solution2.java b/solution/0400-0499/0435.Non-overlapping Intervals/Solution2.java
deleted file mode 100644
index 3db74098111b5..0000000000000
--- a/solution/0400-0499/0435.Non-overlapping Intervals/Solution2.java
+++ /dev/null
@@ -1,32 +0,0 @@
-class Solution {
- public int eraseOverlapIntervals(int[][] intervals) {
- Arrays.sort(intervals, (a, b) -> {
- if (a[0] != b[0]) {
- return a[0] - b[0];
- }
- return a[1] - b[1];
- });
- int n = intervals.length;
- int[] d = new int[n + 1];
- d[1] = intervals[0][1];
- int size = 1;
- for (int i = 1; i < n; ++i) {
- int s = intervals[i][0], e = intervals[i][1];
- if (s >= d[size]) {
- d[++size] = e;
- } else {
- int left = 1, right = size;
- while (left < right) {
- int mid = (left + right) >> 1;
- if (d[mid] >= s) {
- right = mid;
- } else {
- left = mid + 1;
- }
- }
- d[left] = Math.min(d[left], e);
- }
- }
- return n - size;
- }
-}
\ No newline at end of file
diff --git a/solution/0400-0499/0435.Non-overlapping Intervals/Solution2.py b/solution/0400-0499/0435.Non-overlapping Intervals/Solution2.py
deleted file mode 100644
index 8b41845673b4f..0000000000000
--- a/solution/0400-0499/0435.Non-overlapping Intervals/Solution2.py
+++ /dev/null
@@ -1,11 +0,0 @@
-class Solution:
- def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
- intervals.sort()
- d = [intervals[0][1]]
- for s, e in intervals[1:]:
- if s >= d[-1]:
- d.append(e)
- else:
- idx = bisect_left(d, s)
- d[idx] = min(d[idx], e)
- return len(intervals) - len(d)
diff --git a/solution/0400-0499/0437.Path Sum III/README.md b/solution/0400-0499/0437.Path Sum III/README.md
index 193150e562e0f..bf2f873d8f8f2 100644
--- a/solution/0400-0499/0437.Path Sum III/README.md
+++ b/solution/0400-0499/0437.Path Sum III/README.md
@@ -59,18 +59,18 @@ tags:
### 方法一:哈希表 + 前缀和 + 递归
-我们可以运用前缀和的思想,对二叉树进行递归遍历,同时用哈希表 $cnt$ 统计从根节点到当前节点的路径上各个前缀和出现的次数。
+我们可以运用前缀和的思想,对二叉树进行递归遍历,同时用哈希表 $\textit{cnt}$ 统计从根节点到当前节点的路径上各个前缀和出现的次数。
-我们设计一个递归函数 $dfs(node, s)$,表示当前遍历到的节点为 $node$,从根节点到当前节点的路径上的前缀和为 $s$。函数的返回值是统计以 $node$ 节点及其子树节点作为路径终点且路径和为 $targetSum$ 的路径数目。那么答案就是 $dfs(root, 0)$。
+我们设计一个递归函数 $\textit{dfs(node, s)}$,表示当前遍历到的节点为 $\textit{node}$,从根节点到当前节点的路径上的前缀和为 $s$。函数的返回值是统计以 $\textit{node}$ 节点及其子树节点作为路径终点且路径和为 $\textit{targetSum}$ 的路径数目。那么答案就是 $\textit{dfs(root, 0)}$。
-函数 $dfs(node, s)$ 的递归过程如下:
+函数 $\textit{dfs(node, s)}$ 的递归过程如下:
-- 如果当前节点 $node$ 为空,则返回 $0$。
+- 如果当前节点 $\textit{node}$ 为空,则返回 $0$。
- 计算从根节点到当前节点的路径上的前缀和 $s$。
-- 用 $cnt[s - targetSum]$ 表示以当前节点为路径终点且路径和为 $targetSum$ 的路径数目,其中 $cnt[s - targetSum]$ 即为 $cnt$ 中前缀和为 $s - targetSum$ 的个数。
-- 将前缀和 $s$ 的计数值加 $1$,即 $cnt[s] = cnt[s] + 1$。
-- 递归地遍历当前节点的左右子节点,即调用函数 $dfs(node.left, s)$ 和 $dfs(node.right, s)$,并将它们的返回值相加。
-- 在返回值计算完成以后,需要将当前节点的前缀和 $s$ 的计数值减 $1$,即执行 $cnt[s] = cnt[s] - 1$。
+- 用 $\textit{cnt}[s - \textit{targetSum}]$ 表示以当前节点为路径终点且路径和为 $\textit{targetSum}$ 的路径数目,其中 $\textit{cnt}[s - \textit{targetSum}]$ 即为 $\textit{cnt}$ 中前缀和为 $s - \textit{targetSum}$ 的个数。
+- 将前缀和 $s$ 的计数值加 $1$,即 $\textit{cnt}[s] = \textit{cnt}[s] + 1$。
+- 递归地遍历当前节点的左右子节点,即调用函数 $\textit{dfs(node.left, s)}$ 和 $\textit{dfs(node.right, s)}$,并将它们的返回值相加。
+- 在返回值计算完成以后,需要将当前节点的前缀和 $s$ 的计数值减 $1$,即执行 $\textit{cnt}[s] = \textit{cnt}[s] - 1$。
- 最后返回答案。
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是二叉树的节点个数。
@@ -163,10 +163,12 @@ class Solution {
class Solution {
public:
int pathSum(TreeNode* root, int targetSum) {
- unordered_map cnt;
+ unordered_map cnt;
cnt[0] = 1;
- function dfs = [&](TreeNode* node, long s) -> int {
- if (!node) return 0;
+ auto dfs = [&](this auto&& dfs, TreeNode* node, long long s) -> int {
+ if (!node) {
+ return 0;
+ }
s += node->val;
int ans = cnt[s - targetSum];
++cnt[s];
@@ -244,6 +246,129 @@ function pathSum(root: TreeNode | null, targetSum: number): number {
}
```
+#### Rust
+
+```rust
+// Definition for a binary tree node.
+// #[derive(Debug, PartialEq, Eq)]
+// pub struct TreeNode {
+// pub val: i32,
+// pub left: Option>>,
+// pub right: Option>>,
+// }
+//
+// impl TreeNode {
+// #[inline]
+// pub fn new(val: i32) -> Self {
+// TreeNode {
+// val,
+// left: None,
+// right: None
+// }
+// }
+// }
+use std::rc::Rc;
+use std::cell::RefCell;
+use std::collections::HashMap;
+
+impl Solution {
+ pub fn path_sum(root: Option>>, target_sum: i32) -> i32 {
+ let mut cnt = HashMap::new();
+ cnt.insert(0, 1);
+
+ fn dfs(node: Option>>, s: i64, target: i64, cnt: &mut HashMap) -> i32 {
+ if let Some(n) = node {
+ let n = n.borrow();
+ let s = s + n.val as i64;
+ let ans = cnt.get(&(s - target)).copied().unwrap_or(0);
+ *cnt.entry(s).or_insert(0) += 1;
+ let ans = ans + dfs(n.left.clone(), s, target, cnt) + dfs(n.right.clone(), s, target, cnt);
+ *cnt.get_mut(&s).unwrap() -= 1;
+ ans
+ } else {
+ 0
+ }
+ }
+
+ dfs(root, 0, target_sum as i64, &mut cnt)
+ }
+}
+```
+
+#### JavaScript
+
+```js
+/**
+ * Definition for a binary tree node.
+ * function TreeNode(val, left, right) {
+ * this.val = (val===undefined ? 0 : val)
+ * this.left = (left===undefined ? null : left)
+ * this.right = (right===undefined ? null : right)
+ * }
+ */
+/**
+ * @param {TreeNode} root
+ * @param {number} targetSum
+ * @return {number}
+ */
+var pathSum = function (root, targetSum) {
+ const cnt = new Map();
+ const dfs = (node, s) => {
+ if (!node) {
+ return 0;
+ }
+ s += node.val;
+ let ans = cnt.get(s - targetSum) || 0;
+ cnt.set(s, (cnt.get(s) || 0) + 1);
+ ans += dfs(node.left, s);
+ ans += dfs(node.right, s);
+ cnt.set(s, cnt.get(s) - 1);
+ return ans;
+ };
+ cnt.set(0, 1);
+ return dfs(root, 0);
+};
+```
+
+#### C#
+
+```cs
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public int val;
+ * public TreeNode left;
+ * public TreeNode right;
+ * public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) {
+ * this.val = val;
+ * this.left = left;
+ * this.right = right;
+ * }
+ * }
+ */
+public class Solution {
+ public int PathSum(TreeNode root, int targetSum) {
+ Dictionary cnt = new Dictionary();
+
+ int Dfs(TreeNode node, long s) {
+ if (node == null) {
+ return 0;
+ }
+ s += node.val;
+ int ans = cnt.GetValueOrDefault(s - targetSum, 0);
+ cnt[s] = cnt.GetValueOrDefault(s, 0) + 1;
+ ans += Dfs(node.left, s);
+ ans += Dfs(node.right, s);
+ cnt[s]--;
+ return ans;
+ }
+
+ cnt[0] = 1;
+ return Dfs(root, 0);
+ }
+}
+```
+
diff --git a/solution/0400-0499/0437.Path Sum III/README_EN.md b/solution/0400-0499/0437.Path Sum III/README_EN.md
index ebb80e36b0158..0b77c40deaf66 100644
--- a/solution/0400-0499/0437.Path Sum III/README_EN.md
+++ b/solution/0400-0499/0437.Path Sum III/README_EN.md
@@ -53,7 +53,23 @@ tags:
-### Solution 1
+### Solution 1: Hash Table + Prefix Sum + Recursion
+
+We can use the idea of prefix sums to recursively traverse the binary tree while using a hash table $\textit{cnt}$ to count the occurrences of each prefix sum along the path from the root to the current node.
+
+We design a recursive function $\textit{dfs(node, s)}$, where $\textit{node}$ represents the current node being traversed, and $s$ represents the prefix sum along the path from the root to the current node. The return value of the function is the number of paths ending at $\textit{node}$ or its subtree nodes with a sum equal to $\textit{targetSum}$. The final answer is $\textit{dfs(root, 0)}$.
+
+The recursive process of $\textit{dfs(node, s)}$ is as follows:
+
+- If the current node $\textit{node}$ is null, return $0$.
+- Calculate the prefix sum $s$ along the path from the root to the current node.
+- Use $\textit{cnt}[s - \textit{targetSum}]$ to represent the number of paths ending at the current node with a sum equal to $\textit{targetSum}$. Here, $\textit{cnt}[s - \textit{targetSum}]$ is the count of prefix sums equal to $s - \textit{targetSum}$ in $\textit{cnt}$.
+- Increment the count of the prefix sum $s$ by $1$, i.e., $\textit{cnt}[s] = \textit{cnt}[s] + 1$.
+- Recursively traverse the left and right child nodes of the current node by calling $\textit{dfs(node.left, s)}$ and $\textit{dfs(node.right, s)}$, and add their return values.
+- After the return value is calculated, decrement the count of the prefix sum $s$ by $1$, i.e., $\textit{cnt}[s] = \textit{cnt}[s] - 1$.
+- Finally, return the result.
+
+The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the number of nodes in the binary tree.
@@ -143,10 +159,12 @@ class Solution {
class Solution {
public:
int pathSum(TreeNode* root, int targetSum) {
- unordered_map cnt;
+ unordered_map cnt;
cnt[0] = 1;
- function dfs = [&](TreeNode* node, long s) -> int {
- if (!node) return 0;
+ auto dfs = [&](this auto&& dfs, TreeNode* node, long long s) -> int {
+ if (!node) {
+ return 0;
+ }
s += node->val;
int ans = cnt[s - targetSum];
++cnt[s];
@@ -224,6 +242,129 @@ function pathSum(root: TreeNode | null, targetSum: number): number {
}
```
+#### Rust
+
+```rust
+// Definition for a binary tree node.
+// #[derive(Debug, PartialEq, Eq)]
+// pub struct TreeNode {
+// pub val: i32,
+// pub left: Option>>,
+// pub right: Option>>,
+// }
+//
+// impl TreeNode {
+// #[inline]
+// pub fn new(val: i32) -> Self {
+// TreeNode {
+// val,
+// left: None,
+// right: None
+// }
+// }
+// }
+use std::rc::Rc;
+use std::cell::RefCell;
+use std::collections::HashMap;
+
+impl Solution {
+ pub fn path_sum(root: Option>>, target_sum: i32) -> i32 {
+ let mut cnt = HashMap::new();
+ cnt.insert(0, 1);
+
+ fn dfs(node: Option>>, s: i64, target: i64, cnt: &mut HashMap) -> i32 {
+ if let Some(n) = node {
+ let n = n.borrow();
+ let s = s + n.val as i64;
+ let ans = cnt.get(&(s - target)).copied().unwrap_or(0);
+ *cnt.entry(s).or_insert(0) += 1;
+ let ans = ans + dfs(n.left.clone(), s, target, cnt) + dfs(n.right.clone(), s, target, cnt);
+ *cnt.get_mut(&s).unwrap() -= 1;
+ ans
+ } else {
+ 0
+ }
+ }
+
+ dfs(root, 0, target_sum as i64, &mut cnt)
+ }
+}
+```
+
+#### JavaScript
+
+```js
+/**
+ * Definition for a binary tree node.
+ * function TreeNode(val, left, right) {
+ * this.val = (val===undefined ? 0 : val)
+ * this.left = (left===undefined ? null : left)
+ * this.right = (right===undefined ? null : right)
+ * }
+ */
+/**
+ * @param {TreeNode} root
+ * @param {number} targetSum
+ * @return {number}
+ */
+var pathSum = function (root, targetSum) {
+ const cnt = new Map();
+ const dfs = (node, s) => {
+ if (!node) {
+ return 0;
+ }
+ s += node.val;
+ let ans = cnt.get(s - targetSum) || 0;
+ cnt.set(s, (cnt.get(s) || 0) + 1);
+ ans += dfs(node.left, s);
+ ans += dfs(node.right, s);
+ cnt.set(s, cnt.get(s) - 1);
+ return ans;
+ };
+ cnt.set(0, 1);
+ return dfs(root, 0);
+};
+```
+
+#### C#
+
+```cs
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public int val;
+ * public TreeNode left;
+ * public TreeNode right;
+ * public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) {
+ * this.val = val;
+ * this.left = left;
+ * this.right = right;
+ * }
+ * }
+ */
+public class Solution {
+ public int PathSum(TreeNode root, int targetSum) {
+ Dictionary cnt = new Dictionary();
+
+ int Dfs(TreeNode node, long s) {
+ if (node == null) {
+ return 0;
+ }
+ s += node.val;
+ int ans = cnt.GetValueOrDefault(s - targetSum, 0);
+ cnt[s] = cnt.GetValueOrDefault(s, 0) + 1;
+ ans += Dfs(node.left, s);
+ ans += Dfs(node.right, s);
+ cnt[s]--;
+ return ans;
+ }
+
+ cnt[0] = 1;
+ return Dfs(root, 0);
+ }
+}
+```
+
diff --git a/solution/0400-0499/0437.Path Sum III/Solution.cpp b/solution/0400-0499/0437.Path Sum III/Solution.cpp
index 98d9308370efe..8ce3375df8da4 100644
--- a/solution/0400-0499/0437.Path Sum III/Solution.cpp
+++ b/solution/0400-0499/0437.Path Sum III/Solution.cpp
@@ -12,10 +12,12 @@
class Solution {
public:
int pathSum(TreeNode* root, int targetSum) {
- unordered_map cnt;
+ unordered_map cnt;
cnt[0] = 1;
- function dfs = [&](TreeNode* node, long s) -> int {
- if (!node) return 0;
+ auto dfs = [&](this auto&& dfs, TreeNode* node, long long s) -> int {
+ if (!node) {
+ return 0;
+ }
s += node->val;
int ans = cnt[s - targetSum];
++cnt[s];
diff --git a/solution/0400-0499/0437.Path Sum III/Solution.cs b/solution/0400-0499/0437.Path Sum III/Solution.cs
new file mode 100644
index 0000000000000..57b36da47b450
--- /dev/null
+++ b/solution/0400-0499/0437.Path Sum III/Solution.cs
@@ -0,0 +1,34 @@
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ * public int val;
+ * public TreeNode left;
+ * public TreeNode right;
+ * public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) {
+ * this.val = val;
+ * this.left = left;
+ * this.right = right;
+ * }
+ * }
+ */
+public class Solution {
+ public int PathSum(TreeNode root, int targetSum) {
+ Dictionary cnt = new Dictionary();
+
+ int Dfs(TreeNode node, long s) {
+ if (node == null) {
+ return 0;
+ }
+ s += node.val;
+ int ans = cnt.GetValueOrDefault(s - targetSum, 0);
+ cnt[s] = cnt.GetValueOrDefault(s, 0) + 1;
+ ans += Dfs(node.left, s);
+ ans += Dfs(node.right, s);
+ cnt[s]--;
+ return ans;
+ }
+
+ cnt[0] = 1;
+ return Dfs(root, 0);
+ }
+}
diff --git a/solution/0400-0499/0437.Path Sum III/Solution.js b/solution/0400-0499/0437.Path Sum III/Solution.js
new file mode 100644
index 0000000000000..e766757e04c55
--- /dev/null
+++ b/solution/0400-0499/0437.Path Sum III/Solution.js
@@ -0,0 +1,30 @@
+/**
+ * Definition for a binary tree node.
+ * function TreeNode(val, left, right) {
+ * this.val = (val===undefined ? 0 : val)
+ * this.left = (left===undefined ? null : left)
+ * this.right = (right===undefined ? null : right)
+ * }
+ */
+/**
+ * @param {TreeNode} root
+ * @param {number} targetSum
+ * @return {number}
+ */
+var pathSum = function (root, targetSum) {
+ const cnt = new Map();
+ const dfs = (node, s) => {
+ if (!node) {
+ return 0;
+ }
+ s += node.val;
+ let ans = cnt.get(s - targetSum) || 0;
+ cnt.set(s, (cnt.get(s) || 0) + 1);
+ ans += dfs(node.left, s);
+ ans += dfs(node.right, s);
+ cnt.set(s, cnt.get(s) - 1);
+ return ans;
+ };
+ cnt.set(0, 1);
+ return dfs(root, 0);
+};
diff --git a/solution/0400-0499/0437.Path Sum III/Solution.rs b/solution/0400-0499/0437.Path Sum III/Solution.rs
new file mode 100644
index 0000000000000..b7d81d606b273
--- /dev/null
+++ b/solution/0400-0499/0437.Path Sum III/Solution.rs
@@ -0,0 +1,51 @@
+// Definition for a binary tree node.
+// #[derive(Debug, PartialEq, Eq)]
+// pub struct TreeNode {
+// pub val: i32,
+// pub left: Option>>,
+// pub right: Option>>,
+// }
+//
+// impl TreeNode {
+// #[inline]
+// pub fn new(val: i32) -> Self {
+// TreeNode {
+// val,
+// left: None,
+// right: None
+// }
+// }
+// }
+use std::cell::RefCell;
+use std::collections::HashMap;
+use std::rc::Rc;
+
+impl Solution {
+ pub fn path_sum(root: Option>>, target_sum: i32) -> i32 {
+ let mut cnt = HashMap::new();
+ cnt.insert(0, 1);
+
+ fn dfs(
+ node: Option>>,
+ s: i64,
+ target: i64,
+ cnt: &mut HashMap,
+ ) -> i32 {
+ if let Some(n) = node {
+ let n = n.borrow();
+ let s = s + n.val as i64;
+ let ans = cnt.get(&(s - target)).copied().unwrap_or(0);
+ *cnt.entry(s).or_insert(0) += 1;
+ let ans = ans
+ + dfs(n.left.clone(), s, target, cnt)
+ + dfs(n.right.clone(), s, target, cnt);
+ *cnt.get_mut(&s).unwrap() -= 1;
+ ans
+ } else {
+ 0
+ }
+ }
+
+ dfs(root, 0, target_sum as i64, &mut cnt)
+ }
+}
diff --git a/solution/0400-0499/0440.K-th Smallest in Lexicographical Order/README.md b/solution/0400-0499/0440.K-th Smallest in Lexicographical Order/README.md
index 79d1666a074ef..04f5e0e21142b 100644
--- a/solution/0400-0499/0440.K-th Smallest in Lexicographical Order/README.md
+++ b/solution/0400-0499/0440.K-th Smallest in Lexicographical Order/README.md
@@ -49,7 +49,37 @@ tags:
-### 方法一
+### 方法一:字典树计数 + 贪心构造
+
+本题要求在区间 $[1, n]$ 中,按**字典序**排序后,找到第 $k$ 小的数字。由于 $n$ 的范围非常大(最多可达 $10^9$),我们无法直接枚举所有数字后排序。因此我们采用**贪心 + 字典树模拟**的策略。
+
+我们将 $[1, n]$ 看作一棵 **十叉字典树(Trie)**:
+
+- 每个节点是一个前缀,根节点为空串;
+- 节点的子节点是当前前缀拼接上 $0 \sim 9$;
+- 例如前缀 $1$ 会有子节点 $10, 11, \ldots, 19$,而 $10$ 会有 $100, 101, \ldots, 109$;
+- 这种结构天然符合字典序遍历。
+
+```
+根
+├── 1
+│ ├── 10
+│ ├── 11
+│ ├── ...
+├── 2
+├── ...
+```
+
+我们使用变量 $\textit{curr}$ 表示当前前缀,初始为 $1$。每次我们尝试向下扩展前缀,直到找到第 $k$ 小的数字。
+
+每次我们计算当前前缀下有多少个合法数字(即以 $\textit{curr}$ 为前缀、且不超过 $n$ 的整数个数),记作 $\textit{count}(\text{curr})$:
+
+- 如果 $k \ge \text{count}(\text{curr})$:说明目标不在这棵子树中,跳过整棵子树,前缀右移:$\textit{curr} \leftarrow \text{curr} + 1$,并更新 $k \leftarrow k - \text{count}(\text{curr})$;
+- 否则:说明目标在当前前缀的子树中,进入下一层:$\textit{curr} \leftarrow \text{curr} \times 10$,并消耗一个前缀:$k \leftarrow k - 1$。
+
+每一层我们将当前区间扩大 $10$ 倍,向下延伸到更长的前缀,直到超出 $n$。
+
+时间复杂度 $O(\log^2 n)$,空间复杂度 $O(1)$。
@@ -181,6 +211,75 @@ func findKthNumber(n int, k int) int {
}
```
+#### TypeScript
+
+```ts
+function findKthNumber(n: number, k: number): number {
+ function count(curr: number): number {
+ let next = curr + 1;
+ let cnt = 0;
+ while (curr <= n) {
+ cnt += Math.min(n - curr + 1, next - curr);
+ curr *= 10;
+ next *= 10;
+ }
+ return cnt;
+ }
+
+ let curr = 1;
+ k--;
+
+ while (k > 0) {
+ const cnt = count(curr);
+ if (k >= cnt) {
+ k -= cnt;
+ curr += 1;
+ } else {
+ k -= 1;
+ curr *= 10;
+ }
+ }
+
+ return curr;
+}
+```
+
+#### Rust
+
+```rust
+impl Solution {
+ pub fn find_kth_number(n: i32, k: i32) -> i32 {
+ fn count(mut curr: i64, n: i32) -> i32 {
+ let mut next = curr + 1;
+ let mut total = 0;
+ let n = n as i64;
+ while curr <= n {
+ total += std::cmp::min(n - curr + 1, next - curr);
+ curr *= 10;
+ next *= 10;
+ }
+ total as i32
+ }
+
+ let mut curr = 1;
+ let mut k = k - 1;
+
+ while k > 0 {
+ let cnt = count(curr as i64, n);
+ if k >= cnt {
+ k -= cnt;
+ curr += 1;
+ } else {
+ k -= 1;
+ curr *= 10;
+ }
+ }
+
+ curr
+ }
+}
+```
+
diff --git a/solution/0400-0499/0440.K-th Smallest in Lexicographical Order/README_EN.md b/solution/0400-0499/0440.K-th Smallest in Lexicographical Order/README_EN.md
index f8c7bc38a68b3..abdae7d0cad00 100644
--- a/solution/0400-0499/0440.K-th Smallest in Lexicographical Order/README_EN.md
+++ b/solution/0400-0499/0440.K-th Smallest in Lexicographical Order/README_EN.md
@@ -47,7 +47,46 @@ tags:
-### Solution 1
+### Solution 1: Trie-Based Counting + Greedy Construction
+
+The problem asks for the \$k\$-th smallest number in the range $[1, n]$ when all numbers are sorted in **lexicographical order**. Since $n$ can be as large as $10^9$, we cannot afford to generate and sort all the numbers explicitly. Instead, we adopt a strategy based on **greedy traversal over a conceptual Trie**.
+
+We treat the range $[1, n]$ as a **10-ary prefix tree (Trie)**:
+
+- Each node represents a numeric prefix, starting from an empty root;
+- Each node has 10 children, corresponding to appending digits $0 \sim 9$;
+- For example, prefix $1$ has children $10, 11, \ldots, 19$, and node $10$ has children $100, 101, \ldots, 109$;
+- This tree naturally reflects lexicographical order traversal.
+
+```
+root
+├── 1
+│ ├── 10
+│ ├── 11
+│ ├── ...
+├── 2
+├── ...
+```
+
+We use a variable $\textit{curr}$ to denote the current prefix, initialized as $1$. At each step, we try to expand or skip prefixes until we find the \$k\$-th smallest number.
+
+At each step, we calculate how many valid numbers (i.e., numbers $\le n$ with prefix $\textit{curr}$) exist under this prefix subtree. Let this count be $\textit{count}(\text{curr})$:
+
+- If $k \ge \text{count}(\text{curr})$: the target number is not in this subtree. We skip the entire subtree by moving to the next sibling:
+
+ $$
+ \textit{curr} \leftarrow \textit{curr} + 1,\quad k \leftarrow k - \text{count}(\text{curr})
+ $$
+
+- Otherwise: the target is within this subtree. We go one level deeper:
+
+ $$
+ \textit{curr} \leftarrow \textit{curr} \times 10,\quad k \leftarrow k - 1
+ $$
+
+At each level, we enlarge the current range by multiplying by 10 and continue descending until we exceed $n$.
+
+The time complexity is $O(\log^2 n)$, as we perform logarithmic operations for counting and traversing the Trie structure. The space complexity is $O(1)$ since we only use a few variables to track the current prefix and count.
@@ -179,6 +218,75 @@ func findKthNumber(n int, k int) int {
}
```
+#### TypeScript
+
+```ts
+function findKthNumber(n: number, k: number): number {
+ function count(curr: number): number {
+ let next = curr + 1;
+ let cnt = 0;
+ while (curr <= n) {
+ cnt += Math.min(n - curr + 1, next - curr);
+ curr *= 10;
+ next *= 10;
+ }
+ return cnt;
+ }
+
+ let curr = 1;
+ k--;
+
+ while (k > 0) {
+ const cnt = count(curr);
+ if (k >= cnt) {
+ k -= cnt;
+ curr += 1;
+ } else {
+ k -= 1;
+ curr *= 10;
+ }
+ }
+
+ return curr;
+}
+```
+
+#### Rust
+
+```rust
+impl Solution {
+ pub fn find_kth_number(n: i32, k: i32) -> i32 {
+ fn count(mut curr: i64, n: i32) -> i32 {
+ let mut next = curr + 1;
+ let mut total = 0;
+ let n = n as i64;
+ while curr <= n {
+ total += std::cmp::min(n - curr + 1, next - curr);
+ curr *= 10;
+ next *= 10;
+ }
+ total as i32
+ }
+
+ let mut curr = 1;
+ let mut k = k - 1;
+
+ while k > 0 {
+ let cnt = count(curr as i64, n);
+ if k >= cnt {
+ k -= cnt;
+ curr += 1;
+ } else {
+ k -= 1;
+ curr *= 10;
+ }
+ }
+
+ curr
+ }
+}
+```
+
diff --git a/solution/0400-0499/0440.K-th Smallest in Lexicographical Order/Solution.rs b/solution/0400-0499/0440.K-th Smallest in Lexicographical Order/Solution.rs
new file mode 100644
index 0000000000000..52351a5f8ff07
--- /dev/null
+++ b/solution/0400-0499/0440.K-th Smallest in Lexicographical Order/Solution.rs
@@ -0,0 +1,31 @@
+impl Solution {
+ pub fn find_kth_number(n: i32, k: i32) -> i32 {
+ fn count(mut curr: i64, n: i32) -> i32 {
+ let mut next = curr + 1;
+ let mut total = 0;
+ let n = n as i64;
+ while curr <= n {
+ total += std::cmp::min(n - curr + 1, next - curr);
+ curr *= 10;
+ next *= 10;
+ }
+ total as i32
+ }
+
+ let mut curr = 1;
+ let mut k = k - 1;
+
+ while k > 0 {
+ let cnt = count(curr as i64, n);
+ if k >= cnt {
+ k -= cnt;
+ curr += 1;
+ } else {
+ k -= 1;
+ curr *= 10;
+ }
+ }
+
+ curr
+ }
+}
diff --git a/solution/0400-0499/0440.K-th Smallest in Lexicographical Order/Solution.ts b/solution/0400-0499/0440.K-th Smallest in Lexicographical Order/Solution.ts
new file mode 100644
index 0000000000000..7e54456e1b47a
--- /dev/null
+++ b/solution/0400-0499/0440.K-th Smallest in Lexicographical Order/Solution.ts
@@ -0,0 +1,28 @@
+function findKthNumber(n: number, k: number): number {
+ function count(curr: number): number {
+ let next = curr + 1;
+ let cnt = 0;
+ while (curr <= n) {
+ cnt += Math.min(n - curr + 1, next - curr);
+ curr *= 10;
+ next *= 10;
+ }
+ return cnt;
+ }
+
+ let curr = 1;
+ k--;
+
+ while (k > 0) {
+ const cnt = count(curr);
+ if (k >= cnt) {
+ k -= cnt;
+ curr += 1;
+ } else {
+ k -= 1;
+ curr *= 10;
+ }
+ }
+
+ return curr;
+}
diff --git a/solution/0400-0499/0472.Concatenated Words/README.md b/solution/0400-0499/0472.Concatenated Words/README.md
index c487d2cb51c56..31954b9e6721f 100644
--- a/solution/0400-0499/0472.Concatenated Words/README.md
+++ b/solution/0400-0499/0472.Concatenated Words/README.md
@@ -8,6 +8,7 @@ tags:
- 数组
- 字符串
- 动态规划
+ - 排序
---
diff --git a/solution/0400-0499/0472.Concatenated Words/README_EN.md b/solution/0400-0499/0472.Concatenated Words/README_EN.md
index 64039ca4901b3..5635be4155bb9 100644
--- a/solution/0400-0499/0472.Concatenated Words/README_EN.md
+++ b/solution/0400-0499/0472.Concatenated Words/README_EN.md
@@ -8,6 +8,7 @@ tags:
- Array
- String
- Dynamic Programming
+ - Sorting
---
diff --git a/solution/0400-0499/0475.Heaters/README_EN.md b/solution/0400-0499/0475.Heaters/README_EN.md
index 518ecb9eb8201..8b63f1ef8dea6 100644
--- a/solution/0400-0499/0475.Heaters/README_EN.md
+++ b/solution/0400-0499/0475.Heaters/README_EN.md
@@ -25,7 +25,7 @@ tags:
Given the positions of houses and heaters on a horizontal line, return the minimum radius standard of heaters so that those heaters could cover all houses.
-
Notice that all the heaters follow your radius standard, and the warm radius will the same.
+
Notice that all the heaters follow your radius standard, and the warm radius will be the same.
Example 1:
diff --git a/solution/0400-0499/0486.Predict the Winner/README.md b/solution/0400-0499/0486.Predict the Winner/README.md
index 9a5613b1b103c..3750696c8f78e 100644
--- a/solution/0400-0499/0486.Predict the Winner/README.md
+++ b/solution/0400-0499/0486.Predict the Winner/README.md
@@ -63,18 +63,18 @@ tags:
### 方法一:记忆化搜索
-我们设计一个函数 $dfs(i, j)$,表示从第 $i$ 个数到第 $j$ 个数,当前玩家与另一个玩家的得分之差的最大值。那么答案就是 $dfs(0, n - 1) \gt 0$。
+我们设计一个函数 $\textit{dfs}(i, j)$,表示从第 $i$ 个数到第 $j$ 个数,当前玩家与另一个玩家的得分之差的最大值。那么答案就是 $\textit{dfs}(0, n - 1) \geq 0$。
-函数 $dfs(i, j)$ 的计算方法如下:
+函数 $\textit{dfs}(i, j)$ 的计算方法如下:
-- 如果 $i \gt j$,说明当前没有数字了,所以当前玩家没有分数可以拿,差值为 $0$,即 $dfs(i, j) = 0$。
-- 否则,当前玩家有两种选择,如果选择第 $i$ 个数,那么当前玩家与另一个玩家的得分之差为 $nums[i] - dfs(i + 1, j)$;如果选择第 $j$ 个数,那么当前玩家与另一个玩家的得分之差为 $nums[j] - dfs(i, j - 1)$。当前玩家会选择两种情况中差值较大的情况,也就是说 $dfs(i, j) = \max(nums[i] - dfs(i + 1, j), nums[j] - dfs(i, j - 1))$。
+- 如果 $i > j$,说明当前没有数字了,所以当前玩家没有分数可以拿,差值为 $0$,即 $\textit{dfs}(i, j) = 0$。
+- 否则,当前玩家有两种选择,如果选择第 $i$ 个数,那么当前玩家与另一个玩家的得分之差为 $\textit{nums}[i] - \textit{dfs}(i + 1, j)$;如果选择第 $j$ 个数,那么当前玩家与另一个玩家的得分之差为 $\textit{nums}[j] - \textit{dfs}(i, j - 1)$。当前玩家会选择两种情况中差值较大的情况,也就是说 $\textit{dfs}(i, j) = \max(\textit{nums}[i] - \textit{dfs}(i + 1, j), \textit{nums}[j] - \textit{dfs}(i, j - 1))$。
-最后,我们只需要判断 $dfs(0, n - 1) \gt 0$ 即可。
+最后,我们只需要判断 $\textit{dfs}(0, n - 1) \geq 0$ 即可。
-为了避免重复计算,我们可以使用记忆化搜索的方法,用一个数组 $f$ 记录所有的 $dfs(i, j)$ 的值,当函数再次被调用到时,我们可以直接从 $f$ 中取出答案而不需要重新计算。
+为了避免重复计算,我们可以使用记忆化搜索的方法,用一个数组 $f$ 记录所有的 $\textit{dfs}(i, j)$ 的值,当函数再次被调用到时,我们可以直接从 $f$ 中取出答案而不需要重新计算。
-时间复杂度 $O(n^2)$,空间复杂度 $O(n^2)$。其中 $n$ 是数组的长度。
+时间复杂度 $O(n^2)$,空间复杂度 $O(n^2)$。其中 $n$ 是数组 $\textit{nums}$ 的长度。
@@ -82,7 +82,7 @@ tags:
```python
class Solution:
- def PredictTheWinner(self, nums: List[int]) -> bool:
+ def predictTheWinner(self, nums: List[int]) -> bool:
@cache
def dfs(i: int, j: int) -> int:
if i > j:
@@ -99,7 +99,7 @@ class Solution {
private int[] nums;
private int[][] f;
- public boolean PredictTheWinner(int[] nums) {
+ public boolean predictTheWinner(int[] nums) {
this.nums = nums;
int n = nums.length;
f = new int[n][n];
@@ -123,11 +123,10 @@ class Solution {
```cpp
class Solution {
public:
- bool PredictTheWinner(vector& nums) {
+ bool predictTheWinner(vector& nums) {
int n = nums.size();
- int f[n][n];
- memset(f, 0, sizeof(f));
- function dfs = [&](int i, int j) -> int {
+ vector> f(n, vector(n));
+ auto dfs = [&](this auto&& dfs, int i, int j) -> int {
if (i > j) {
return 0;
}
@@ -144,7 +143,7 @@ public:
#### Go
```go
-func PredictTheWinner(nums []int) bool {
+func predictTheWinner(nums []int) bool {
n := len(nums)
f := make([][]int, n)
for i := range f {
@@ -167,9 +166,9 @@ func PredictTheWinner(nums []int) bool {
#### TypeScript
```ts
-function PredictTheWinner(nums: number[]): boolean {
+function predictTheWinner(nums: number[]): boolean {
const n = nums.length;
- const f: number[][] = new Array(n).fill(0).map(() => new Array(n).fill(0));
+ const f: number[][] = Array.from({ length: n }, () => Array(n).fill(0));
const dfs = (i: number, j: number): number => {
if (i > j) {
return 0;
@@ -187,29 +186,24 @@ function PredictTheWinner(nums: number[]): boolean {
```rust
impl Solution {
- #[allow(dead_code)]
pub fn predict_the_winner(nums: Vec) -> bool {
let n = nums.len();
- let mut dp: Vec> = vec![vec![0; n]; n];
+ let mut f = vec![vec![0; n]; n];
+ Self::dfs(&nums, &mut f, 0, n - 1) >= 0
+ }
- // Initialize the dp vector
- for i in 0..n {
- dp[i][i] = nums[i];
+ fn dfs(nums: &Vec, f: &mut Vec>, i: usize, j: usize) -> i32 {
+ if i == j {
+ return nums[i] as i32;
}
-
- // Begin the dp process
- for i in (0..n - 1).rev() {
- for j in i + 1..n {
- dp[i][j] = std::cmp::max(
- // Take i-th num
- nums[i] - dp[i + 1][j],
- // Take j-th num
- nums[j] - dp[i][j - 1],
- );
- }
+ if f[i][j] != 0 {
+ return f[i][j];
}
-
- dp[0][n - 1] >= 0
+ f[i][j] = std::cmp::max(
+ nums[i] - Self::dfs(nums, f, i + 1, j),
+ nums[j] - Self::dfs(nums, f, i, j - 1)
+ );
+ f[i][j]
}
}
```
@@ -222,20 +216,20 @@ impl Solution {
### 方法二:动态规划
-我们也可以使用动态规划的方法,定义 $f[i][j]$ 表示当前玩家在 $nums[i..j]$ 这些数字中能够获得的最大得分的差值。那么最后答案就是 $f[0][n - 1] \gt 0$。
+我们也可以使用动态规划的方法,定义 $f[i][j]$ 表示当前玩家在 $\textit{nums}[i..j]$ 这些数字中能够获得的最大得分的差值。那么最后答案就是 $f[0][n - 1] \geq 0$。
-初始时 $f[i][i]=nums[i]$,因为只有一个数,所以当前玩家只能拿取这个数,得分差值为 $nums[i]$。
+初始时 $f[i][i]=\textit{nums}[i]$,因为只有一个数,所以当前玩家只能拿取这个数,得分差值为 $\textit{nums}[i]$。
-考虑 $f[i][j]$,其中 $i \lt j$,有两种情况:
+考虑 $f[i][j]$,其中 $i < j$,有两种情况:
-- 如果当前玩家拿走了 $nums[i]$,那么剩下的数字为 $nums[i + 1..j]$,此时轮到另一个玩家进行游戏,所以 $f[i][j] = nums[i] - f[i + 1][j]$。
-- 如果当前玩家拿走了 $nums[j]$,那么剩下的数字为 $nums[i..j - 1]$,此时轮到另一个玩家进行游戏,所以 $f[i][j] = nums[j] - f[i][j - 1]$。
+- 如果当前玩家拿走了 $\textit{nums}[i]$,那么剩下的数字为 $\textit{nums}[i + 1..j]$,此时轮到另一个玩家进行游戏,所以 $f[i][j] = \textit{nums}[i] - f[i + 1][j]$。
+- 如果当前玩家拿走了 $\textit{nums}[j]$,那么剩下的数字为 $\textit{nums}[i..j - 1]$,此时轮到另一个玩家进行游戏,所以 $f[i][j] = \textit{nums}[j] - f[i][j - 1]$。
-因此,最终的状态转移方程为 $f[i][j] = \max(nums[i] - f[i + 1][j], nums[j] - f[i][j - 1])$。
+因此,最终的状态转移方程为 $f[i][j] = \max(\textit{nums}[i] - f[i + 1][j], \textit{nums}[j] - f[i][j - 1])$。
-最后,我们只需要判断 $f[0][n - 1] \gt 0$ 即可。
+最后,我们只需要判断 $f[0][n - 1] \geq 0$ 即可。
-时间复杂度 $O(n^2)$,空间复杂度 $O(n^2)$。其中 $n$ 是数组的长度。
+时间复杂度 $O(n^2)$,空间复杂度 $O(n^2)$。其中 $n$ 是数组 $\textit{nums}$ 的长度。
相似题目:
@@ -247,7 +241,7 @@ impl Solution {
```python
class Solution:
- def PredictTheWinner(self, nums: List[int]) -> bool:
+ def predictTheWinner(self, nums: List[int]) -> bool:
n = len(nums)
f = [[0] * n for _ in range(n)]
for i, x in enumerate(nums):
@@ -262,7 +256,7 @@ class Solution:
```java
class Solution {
- public boolean PredictTheWinner(int[] nums) {
+ public boolean predictTheWinner(int[] nums) {
int n = nums.length;
int[][] f = new int[n][n];
for (int i = 0; i < n; ++i) {
@@ -283,7 +277,7 @@ class Solution {
```cpp
class Solution {
public:
- bool PredictTheWinner(vector& nums) {
+ bool predictTheWinner(vector& nums) {
int n = nums.size();
int f[n][n];
memset(f, 0, sizeof(f));
@@ -303,7 +297,7 @@ public:
#### Go
```go
-func PredictTheWinner(nums []int) bool {
+func predictTheWinner(nums []int) bool {
n := len(nums)
f := make([][]int, n)
for i, x := range nums {
@@ -322,9 +316,9 @@ func PredictTheWinner(nums []int) bool {
#### TypeScript
```ts
-function PredictTheWinner(nums: number[]): boolean {
+function predictTheWinner(nums: number[]): boolean {
const n = nums.length;
- const f: number[][] = new Array(n).fill(0).map(() => new Array(n).fill(0));
+ const f: number[][] = Array.from({ length: n }, () => Array(n).fill(0));
for (let i = 0; i < n; ++i) {
f[i][i] = nums[i];
}
@@ -337,6 +331,29 @@ function PredictTheWinner(nums: number[]): boolean {
}
```
+#### Rust
+
+```rust
+impl Solution {
+ pub fn predict_the_winner(nums: Vec) -> bool {
+ let n = nums.len();
+ let mut f = vec![vec![0; n]; n];
+
+ for i in 0..n {
+ f[i][i] = nums[i];
+ }
+
+ for i in (0..n - 1).rev() {
+ for j in i + 1..n {
+ f[i][j] = std::cmp::max(nums[i] - f[i + 1][j], nums[j] - f[i][j - 1]);
+ }
+ }
+
+ f[0][n - 1] >= 0
+ }
+}
+```
+
diff --git a/solution/0400-0499/0486.Predict the Winner/README_EN.md b/solution/0400-0499/0486.Predict the Winner/README_EN.md
index 88171f6b2f1b1..187dde4159126 100644
--- a/solution/0400-0499/0486.Predict the Winner/README_EN.md
+++ b/solution/0400-0499/0486.Predict the Winner/README_EN.md
@@ -61,7 +61,20 @@ Finally, player 1 has more score (234) than player 2 (12), so you need to return
-### Solution 1
+### Solution 1: Memoization Search
+
+We design a function $\textit{dfs}(i, j)$, which represents the maximum difference in scores between the current player and the other player from the $i$-th number to the $j$-th number. The answer is $\textit{dfs}(0, n - 1) \geq 0$.
+
+The function $\textit{dfs}(i, j)$ is calculated as follows:
+
+- If $i > j$, it means there are no numbers left, so the current player cannot take any points, and the difference is $0$, i.e., $\textit{dfs}(i, j) = 0$.
+- Otherwise, the current player has two choices. If they choose the $i$-th number, the difference in scores between the current player and the other player is $\textit{nums}[i] - \textit{dfs}(i + 1, j)$. If they choose the $j$-th number, the difference in scores between the current player and the other player is $\textit{nums}[j] - \textit{dfs}(i, j - 1)$. The current player will choose the option with the larger difference, so $\textit{dfs}(i, j) = \max(\textit{nums}[i] - \textit{dfs}(i + 1, j), \textit{nums}[j] - \textit{dfs}(i, j - 1))$.
+
+Finally, we only need to check if $\textit{dfs}(0, n - 1) \geq 0$.
+
+To avoid repeated calculations, we can use memoization. We use an array $f$ to record all the values of $\textit{dfs}(i, j)$. When the function is called again, we can directly retrieve the answer from $f$ without recalculating it.
+
+The time complexity is $O(n^2)$, and the space complexity is $O(n^2)$. Here, $n$ is the length of the array $\textit{nums}$.
@@ -69,7 +82,7 @@ Finally, player 1 has more score (234) than player 2 (12), so you need to return
```python
class Solution:
- def PredictTheWinner(self, nums: List[int]) -> bool:
+ def predictTheWinner(self, nums: List[int]) -> bool:
@cache
def dfs(i: int, j: int) -> int:
if i > j:
@@ -86,7 +99,7 @@ class Solution {
private int[] nums;
private int[][] f;
- public boolean PredictTheWinner(int[] nums) {
+ public boolean predictTheWinner(int[] nums) {
this.nums = nums;
int n = nums.length;
f = new int[n][n];
@@ -110,11 +123,10 @@ class Solution {
```cpp
class Solution {
public:
- bool PredictTheWinner(vector& nums) {
+ bool predictTheWinner(vector& nums) {
int n = nums.size();
- int f[n][n];
- memset(f, 0, sizeof(f));
- function dfs = [&](int i, int j) -> int {
+ vector> f(n, vector(n));
+ auto dfs = [&](this auto&& dfs, int i, int j) -> int {
if (i > j) {
return 0;
}
@@ -131,7 +143,7 @@ public:
#### Go
```go
-func PredictTheWinner(nums []int) bool {
+func predictTheWinner(nums []int) bool {
n := len(nums)
f := make([][]int, n)
for i := range f {
@@ -154,9 +166,9 @@ func PredictTheWinner(nums []int) bool {
#### TypeScript
```ts
-function PredictTheWinner(nums: number[]): boolean {
+function predictTheWinner(nums: number[]): boolean {
const n = nums.length;
- const f: number[][] = new Array(n).fill(0).map(() => new Array(n).fill(0));
+ const f: number[][] = Array.from({ length: n }, () => Array(n).fill(0));
const dfs = (i: number, j: number): number => {
if (i > j) {
return 0;
@@ -174,29 +186,24 @@ function PredictTheWinner(nums: number[]): boolean {
```rust
impl Solution {
- #[allow(dead_code)]
pub fn predict_the_winner(nums: Vec) -> bool {
let n = nums.len();
- let mut dp: Vec> = vec![vec![0; n]; n];
+ let mut f = vec![vec![0; n]; n];
+ Self::dfs(&nums, &mut f, 0, n - 1) >= 0
+ }
- // Initialize the dp vector
- for i in 0..n {
- dp[i][i] = nums[i];
+ fn dfs(nums: &Vec, f: &mut Vec>, i: usize, j: usize) -> i32 {
+ if i == j {
+ return nums[i] as i32;
}
-
- // Begin the dp process
- for i in (0..n - 1).rev() {
- for j in i + 1..n {
- dp[i][j] = std::cmp::max(
- // Take i-th num
- nums[i] - dp[i + 1][j],
- // Take j-th num
- nums[j] - dp[i][j - 1],
- );
- }
+ if f[i][j] != 0 {
+ return f[i][j];
}
-
- dp[0][n - 1] >= 0
+ f[i][j] = std::cmp::max(
+ nums[i] - Self::dfs(nums, f, i + 1, j),
+ nums[j] - Self::dfs(nums, f, i, j - 1)
+ );
+ f[i][j]
}
}
```
@@ -207,7 +214,26 @@ impl Solution {
-### Solution 2
+### Solution 2: Dynamic Programming
+
+We can also use dynamic programming. Define $f[i][j]$ to represent the maximum score difference the current player can achieve in the range $\textit{nums}[i..j]$. The final answer is $f[0][n - 1] \geq 0$.
+
+Initially, $f[i][i] = \textit{nums}[i]$, because with only one number, the current player can only take that number, and the score difference is $\textit{nums}[i]$.
+
+Consider $f[i][j]$ where $i < j$, there are two cases:
+
+- If the current player takes $\textit{nums}[i]$, the remaining numbers are $\textit{nums}[i + 1..j]$, and it is the other player's turn. So, $f[i][j] = \textit{nums}[i] - f[i + 1][j]$.
+- If the current player takes $\textit{nums}[j]$, the remaining numbers are $\textit{nums}[i..j - 1]$, and it is the other player's turn. So, $f[i][j] = \textit{nums}[j] - f[i][j - 1]$.
+
+Therefore, the state transition equation is $f[i][j] = \max(\textit{nums}[i] - f[i + 1][j], \textit{nums}[j] - f[i][j - 1])$.
+
+Finally, we only need to check if $f[0][n - 1] \geq 0$.
+
+The time complexity is $O(n^2)$, and the space complexity is $O(n^2)$. Here, $n$ is the length of the array $\textit{nums}$.
+
+Similar problem:
+
+- [877. Stone Game](https://github.com/doocs/leetcode/blob/main/solution/0800-0899/0877.Stone%20Game/README_EN.md)
@@ -215,7 +241,7 @@ impl Solution {
```python
class Solution:
- def PredictTheWinner(self, nums: List[int]) -> bool:
+ def predictTheWinner(self, nums: List[int]) -> bool:
n = len(nums)
f = [[0] * n for _ in range(n)]
for i, x in enumerate(nums):
@@ -230,7 +256,7 @@ class Solution:
```java
class Solution {
- public boolean PredictTheWinner(int[] nums) {
+ public boolean predictTheWinner(int[] nums) {
int n = nums.length;
int[][] f = new int[n][n];
for (int i = 0; i < n; ++i) {
@@ -251,7 +277,7 @@ class Solution {
```cpp
class Solution {
public:
- bool PredictTheWinner(vector& nums) {
+ bool predictTheWinner(vector& nums) {
int n = nums.size();
int f[n][n];
memset(f, 0, sizeof(f));
@@ -271,7 +297,7 @@ public:
#### Go
```go
-func PredictTheWinner(nums []int) bool {
+func predictTheWinner(nums []int) bool {
n := len(nums)
f := make([][]int, n)
for i, x := range nums {
@@ -290,9 +316,9 @@ func PredictTheWinner(nums []int) bool {
#### TypeScript
```ts
-function PredictTheWinner(nums: number[]): boolean {
+function predictTheWinner(nums: number[]): boolean {
const n = nums.length;
- const f: number[][] = new Array(n).fill(0).map(() => new Array(n).fill(0));
+ const f: number[][] = Array.from({ length: n }, () => Array(n).fill(0));
for (let i = 0; i < n; ++i) {
f[i][i] = nums[i];
}
@@ -305,6 +331,29 @@ function PredictTheWinner(nums: number[]): boolean {
}
```
+#### Rust
+
+```rust
+impl Solution {
+ pub fn predict_the_winner(nums: Vec) -> bool {
+ let n = nums.len();
+ let mut f = vec![vec![0; n]; n];
+
+ for i in 0..n {
+ f[i][i] = nums[i];
+ }
+
+ for i in (0..n - 1).rev() {
+ for j in i + 1..n {
+ f[i][j] = std::cmp::max(nums[i] - f[i + 1][j], nums[j] - f[i][j - 1]);
+ }
+ }
+
+ f[0][n - 1] >= 0
+ }
+}
+```
+
diff --git a/solution/0400-0499/0486.Predict the Winner/Solution.cpp b/solution/0400-0499/0486.Predict the Winner/Solution.cpp
index 58f6253f0ffdb..e25e23d7b9fb4 100644
--- a/solution/0400-0499/0486.Predict the Winner/Solution.cpp
+++ b/solution/0400-0499/0486.Predict the Winner/Solution.cpp
@@ -1,10 +1,9 @@
class Solution {
public:
- bool PredictTheWinner(vector& nums) {
+ bool predictTheWinner(vector& nums) {
int n = nums.size();
- int f[n][n];
- memset(f, 0, sizeof(f));
- function dfs = [&](int i, int j) -> int {
+ vector> f(n, vector(n));
+ auto dfs = [&](this auto&& dfs, int i, int j) -> int {
if (i > j) {
return 0;
}
diff --git a/solution/0400-0499/0486.Predict the Winner/Solution.go b/solution/0400-0499/0486.Predict the Winner/Solution.go
index d9d1cb82a6a71..2f2229a5586e8 100644
--- a/solution/0400-0499/0486.Predict the Winner/Solution.go
+++ b/solution/0400-0499/0486.Predict the Winner/Solution.go
@@ -1,4 +1,4 @@
-func PredictTheWinner(nums []int) bool {
+func predictTheWinner(nums []int) bool {
n := len(nums)
f := make([][]int, n)
for i := range f {
diff --git a/solution/0400-0499/0486.Predict the Winner/Solution.java b/solution/0400-0499/0486.Predict the Winner/Solution.java
index 7cd2834256a20..eaf68e12830ed 100644
--- a/solution/0400-0499/0486.Predict the Winner/Solution.java
+++ b/solution/0400-0499/0486.Predict the Winner/Solution.java
@@ -2,7 +2,7 @@ class Solution {
private int[] nums;
private int[][] f;
- public boolean PredictTheWinner(int[] nums) {
+ public boolean predictTheWinner(int[] nums) {
this.nums = nums;
int n = nums.length;
f = new int[n][n];
diff --git a/solution/0400-0499/0486.Predict the Winner/Solution.py b/solution/0400-0499/0486.Predict the Winner/Solution.py
index 577b203921414..ded115095a38a 100644
--- a/solution/0400-0499/0486.Predict the Winner/Solution.py
+++ b/solution/0400-0499/0486.Predict the Winner/Solution.py
@@ -1,5 +1,5 @@
class Solution:
- def PredictTheWinner(self, nums: List[int]) -> bool:
+ def predictTheWinner(self, nums: List[int]) -> bool:
@cache
def dfs(i: int, j: int) -> int:
if i > j:
diff --git a/solution/0400-0499/0486.Predict the Winner/Solution.rs b/solution/0400-0499/0486.Predict the Winner/Solution.rs
index b6ad1ea47965a..5757d0ae3acb5 100644
--- a/solution/0400-0499/0486.Predict the Winner/Solution.rs
+++ b/solution/0400-0499/0486.Predict the Winner/Solution.rs
@@ -1,26 +1,21 @@
impl Solution {
- #[allow(dead_code)]
pub fn predict_the_winner(nums: Vec) -> bool {
let n = nums.len();
- let mut dp: Vec> = vec![vec![0; n]; n];
+ let mut f = vec![vec![0; n]; n];
+ Self::dfs(&nums, &mut f, 0, n - 1) >= 0
+ }
- // Initialize the dp vector
- for i in 0..n {
- dp[i][i] = nums[i];
+ fn dfs(nums: &Vec, f: &mut Vec>, i: usize, j: usize) -> i32 {
+ if i == j {
+ return nums[i] as i32;
}
-
- // Begin the dp process
- for i in (0..n - 1).rev() {
- for j in i + 1..n {
- dp[i][j] = std::cmp::max(
- // Take i-th num
- nums[i] - dp[i + 1][j],
- // Take j-th num
- nums[j] - dp[i][j - 1],
- );
- }
+ if f[i][j] != 0 {
+ return f[i][j];
}
-
- dp[0][n - 1] >= 0
+ f[i][j] = std::cmp::max(
+ nums[i] - Self::dfs(nums, f, i + 1, j),
+ nums[j] - Self::dfs(nums, f, i, j - 1),
+ );
+ f[i][j]
}
}
diff --git a/solution/0400-0499/0486.Predict the Winner/Solution.ts b/solution/0400-0499/0486.Predict the Winner/Solution.ts
index 1cb89afa05346..585a42b7f0034 100644
--- a/solution/0400-0499/0486.Predict the Winner/Solution.ts
+++ b/solution/0400-0499/0486.Predict the Winner/Solution.ts
@@ -1,6 +1,6 @@
-function PredictTheWinner(nums: number[]): boolean {
+function predictTheWinner(nums: number[]): boolean {
const n = nums.length;
- const f: number[][] = new Array(n).fill(0).map(() => new Array(n).fill(0));
+ const f: number[][] = Array.from({ length: n }, () => Array(n).fill(0));
const dfs = (i: number, j: number): number => {
if (i > j) {
return 0;
diff --git a/solution/0400-0499/0486.Predict the Winner/Solution2.cpp b/solution/0400-0499/0486.Predict the Winner/Solution2.cpp
index 0d919bbf17695..86664de5ca6da 100644
--- a/solution/0400-0499/0486.Predict the Winner/Solution2.cpp
+++ b/solution/0400-0499/0486.Predict the Winner/Solution2.cpp
@@ -1,6 +1,6 @@
class Solution {
public:
- bool PredictTheWinner(vector& nums) {
+ bool predictTheWinner(vector& nums) {
int n = nums.size();
int f[n][n];
memset(f, 0, sizeof(f));
diff --git a/solution/0400-0499/0486.Predict the Winner/Solution2.go b/solution/0400-0499/0486.Predict the Winner/Solution2.go
index 8becdf3e650b3..384c300459ceb 100644
--- a/solution/0400-0499/0486.Predict the Winner/Solution2.go
+++ b/solution/0400-0499/0486.Predict the Winner/Solution2.go
@@ -1,4 +1,4 @@
-func PredictTheWinner(nums []int) bool {
+func predictTheWinner(nums []int) bool {
n := len(nums)
f := make([][]int, n)
for i, x := range nums {
diff --git a/solution/0400-0499/0486.Predict the Winner/Solution2.java b/solution/0400-0499/0486.Predict the Winner/Solution2.java
index 8ba95d347bf20..e664f055fcb3c 100644
--- a/solution/0400-0499/0486.Predict the Winner/Solution2.java
+++ b/solution/0400-0499/0486.Predict the Winner/Solution2.java
@@ -1,5 +1,5 @@
class Solution {
- public boolean PredictTheWinner(int[] nums) {
+ public boolean predictTheWinner(int[] nums) {
int n = nums.length;
int[][] f = new int[n][n];
for (int i = 0; i < n; ++i) {
diff --git a/solution/0400-0499/0486.Predict the Winner/Solution2.py b/solution/0400-0499/0486.Predict the Winner/Solution2.py
index ea29b78c717a7..7e1f345c281da 100644
--- a/solution/0400-0499/0486.Predict the Winner/Solution2.py
+++ b/solution/0400-0499/0486.Predict the Winner/Solution2.py
@@ -1,5 +1,5 @@
class Solution:
- def PredictTheWinner(self, nums: List[int]) -> bool:
+ def predictTheWinner(self, nums: List[int]) -> bool:
n = len(nums)
f = [[0] * n for _ in range(n)]
for i, x in enumerate(nums):
diff --git a/solution/0400-0499/0486.Predict the Winner/Solution2.rs b/solution/0400-0499/0486.Predict the Winner/Solution2.rs
new file mode 100644
index 0000000000000..5da7136ca4661
--- /dev/null
+++ b/solution/0400-0499/0486.Predict the Winner/Solution2.rs
@@ -0,0 +1,18 @@
+impl Solution {
+ pub fn predict_the_winner(nums: Vec) -> bool {
+ let n = nums.len();
+ let mut f = vec![vec![0; n]; n];
+
+ for i in 0..n {
+ f[i][i] = nums[i];
+ }
+
+ for i in (0..n - 1).rev() {
+ for j in i + 1..n {
+ f[i][j] = std::cmp::max(nums[i] - f[i + 1][j], nums[j] - f[i][j - 1]);
+ }
+ }
+
+ f[0][n - 1] >= 0
+ }
+}
diff --git a/solution/0400-0499/0486.Predict the Winner/Solution2.ts b/solution/0400-0499/0486.Predict the Winner/Solution2.ts
index b276dadc5cb88..ec8f5d5908551 100644
--- a/solution/0400-0499/0486.Predict the Winner/Solution2.ts
+++ b/solution/0400-0499/0486.Predict the Winner/Solution2.ts
@@ -1,6 +1,6 @@
-function PredictTheWinner(nums: number[]): boolean {
+function predictTheWinner(nums: number[]): boolean {
const n = nums.length;
- const f: number[][] = new Array(n).fill(0).map(() => new Array(n).fill(0));
+ const f: number[][] = Array.from({ length: n }, () => Array(n).fill(0));
for (let i = 0; i < n; ++i) {
f[i][i] = nums[i];
}
diff --git a/solution/0400-0499/0499.The Maze III/README.md b/solution/0400-0499/0499.The Maze III/README.md
index 65546e7027af0..8b82449612cf2 100644
--- a/solution/0400-0499/0499.The Maze III/README.md
+++ b/solution/0400-0499/0499.The Maze III/README.md
@@ -23,9 +23,9 @@ tags:
-
There is a ball in a maze with empty spaces (represented as 0) and walls (represented as 1). The ball can go through the empty spaces by rolling up, down, left or right, but it won't stop rolling until hitting a wall. When the ball stops, it could choose the next direction. There is also a hole in this maze. The ball will drop into the hole if it rolls onto the hole.
+
There is a ball in a maze with empty spaces (represented as 0) and walls (represented as 1). The ball can go through the empty spaces by rolling up, down, left or right, but it won't stop rolling until hitting a wall. When the ball stops, it could choose the next direction (must be different from last chosen direction). There is also a hole in this maze. The ball will drop into the hole if it rolls onto the hole.
Given the m x nmaze, the ball's position ball and the hole's position hole, where ball = [ballrow, ballcol] and hole = [holerow, holecol], return a string instructions of all the instructions that the ball should follow to drop in the hole with the shortest distance possible. If there are multiple valid instructions, return the lexicographically minimum one. If the ball can't drop in the hole, return "impossible".
diff --git a/solution/0500-0599/0504.Base 7/README.md b/solution/0500-0599/0504.Base 7/README.md
index 1e955a5f67ddb..4777530cac658 100644
--- a/solution/0500-0599/0504.Base 7/README.md
+++ b/solution/0500-0599/0504.Base 7/README.md
@@ -4,6 +4,7 @@ difficulty: 简单
edit_url: https://github.com/doocs/leetcode/edit/main/solution/0500-0599/0504.Base%207/README.md
tags:
- 数学
+ - 字符串
---
diff --git a/solution/0500-0599/0504.Base 7/README_EN.md b/solution/0500-0599/0504.Base 7/README_EN.md
index c769e0816a5eb..20c58cdef8dff 100644
--- a/solution/0500-0599/0504.Base 7/README_EN.md
+++ b/solution/0500-0599/0504.Base 7/README_EN.md
@@ -4,6 +4,7 @@ difficulty: Easy
edit_url: https://github.com/doocs/leetcode/edit/main/solution/0500-0599/0504.Base%207/README_EN.md
tags:
- Math
+ - String
---
diff --git a/solution/0500-0599/0506.Relative Ranks/README.md b/solution/0500-0599/0506.Relative Ranks/README.md
index 2f1fa1b09f81b..8dc348d38fa3e 100644
--- a/solution/0500-0599/0506.Relative Ranks/README.md
+++ b/solution/0500-0599/0506.Relative Ranks/README.md
@@ -97,9 +97,7 @@ class Solution {
public String[] findRelativeRanks(int[] score) {
int n = score.length;
Integer[] idx = new Integer[n];
- for (int i = 0; i < n; ++i) {
- idx[i] = i;
- }
+ Arrays.setAll(idx, i -> i);
Arrays.sort(idx, (i1, i2) -> score[i2] - score[i1]);
String[] ans = new String[n];
String[] top3 = new String[] {"Gold Medal", "Silver Medal", "Bronze Medal"};
diff --git a/solution/0500-0599/0506.Relative Ranks/README_EN.md b/solution/0500-0599/0506.Relative Ranks/README_EN.md
index 8bb99b92b780c..7abeba13e8be4 100644
--- a/solution/0500-0599/0506.Relative Ranks/README_EN.md
+++ b/solution/0500-0599/0506.Relative Ranks/README_EN.md
@@ -96,9 +96,7 @@ class Solution {
public String[] findRelativeRanks(int[] score) {
int n = score.length;
Integer[] idx = new Integer[n];
- for (int i = 0; i < n; ++i) {
- idx[i] = i;
- }
+ Arrays.setAll(idx, i -> i);
Arrays.sort(idx, (i1, i2) -> score[i2] - score[i1]);
String[] ans = new String[n];
String[] top3 = new String[] {"Gold Medal", "Silver Medal", "Bronze Medal"};
diff --git a/solution/0500-0599/0506.Relative Ranks/Solution.java b/solution/0500-0599/0506.Relative Ranks/Solution.java
index 700c854e36bcb..a855b14e5cb57 100644
--- a/solution/0500-0599/0506.Relative Ranks/Solution.java
+++ b/solution/0500-0599/0506.Relative Ranks/Solution.java
@@ -2,9 +2,7 @@ class Solution {
public String[] findRelativeRanks(int[] score) {
int n = score.length;
Integer[] idx = new Integer[n];
- for (int i = 0; i < n; ++i) {
- idx[i] = i;
- }
+ Arrays.setAll(idx, i -> i);
Arrays.sort(idx, (i1, i2) -> score[i2] - score[i1]);
String[] ans = new String[n];
String[] top3 = new String[] {"Gold Medal", "Silver Medal", "Bronze Medal"};
diff --git a/solution/0500-0599/0520.Detect Capital/README.md b/solution/0500-0599/0520.Detect Capital/README.md
index b97c875d43010..ecb68de064c73 100644
--- a/solution/0500-0599/0520.Detect Capital/README.md
+++ b/solution/0500-0599/0520.Detect Capital/README.md
@@ -20,8 +20,8 @@ tags:
diff --git a/solution/0500-0599/0550.Game Play Analysis IV/README_EN.md b/solution/0500-0599/0550.Game Play Analysis IV/README_EN.md
index 75774152565b6..3612f647d84ed 100644
--- a/solution/0500-0599/0550.Game Play Analysis IV/README_EN.md
+++ b/solution/0500-0599/0550.Game Play Analysis IV/README_EN.md
@@ -32,11 +32,11 @@ This table shows the activity of players of some games.
Each row is a record of a player who logged in and played a number of games (possibly 0) before logging out on someday using some device.
-
+
-
Write a solution to report the fraction of players that logged in again on the day after the day they first logged in, rounded to 2 decimal places. In other words, you need to count the number of players that logged in for at least two consecutive days starting from their first login date, then divide that number by the total number of players.
+
Write a solution to report the fraction of players that logged in again on the day after the day they first logged in, rounded to 2 decimal places. In other words, you need to determine the number of players who logged in on the day immediately following their initial login, and divide it by the number of total players.
-
The result format is in the following example.
+
The result format is in the following example.
Example 1:
diff --git a/solution/0500-0599/0568.Maximum Vacation Days/README.md b/solution/0500-0599/0568.Maximum Vacation Days/README.md
index 0b759e9bf93c8..c482a1c70a038 100644
--- a/solution/0500-0599/0568.Maximum Vacation Days/README.md
+++ b/solution/0500-0599/0568.Maximum Vacation Days/README.md
@@ -98,7 +98,7 @@ Ans = 7 + 7 + 7 = 21
我们定义 $f[k][j]$ 表示前 $k$ 周,且最后一周在城市 $j$ 休假的最长天数。初始时 $f[0][0]=0$,其它 $f[0][j]=-\infty$。答案为 $\max_{j=0}^{n-1} f[K][j]$。
-接下来,我们考虑如何计算 $f[k][j]$。对于当前这一周,我们可以枚举上一周所在的城市 $i$,城市 $i$ 可以和城市 $j$ 相等,那么 $f[k][j] = f[k-1][i]$;也可以和城市 $j$ 不相等,如果不相等,我们需要判断是否可以从城市 $i$ 飞到城市 $j$,如果可以,那么 $f[k][j] = max(f[k][j], f[k-1][i])$。最后,我们还需要加上这一周在城市 $j$ 休假的天数 $days[j][k-1]$。
+接下来,我们考虑如何计算 $f[k][j]$。对于当前这一周,我们可以枚举上一周所在的城市 $i$,城市 $i$ 可以和城市 $j$ 相等,那么 $f[k][j] = f[k-1][i]$;也可以和城市 $j$ 不相等,如果不相等,我们需要判断是否可以从城市 $i$ 飞到城市 $j$,如果可以,那么 $f[k][j] = \max(f[k][j], f[k-1][i])$。最后,我们还需要加上这一周在城市 $j$ 休假的天数 $\textit{days}[j][k-1]$。
最终的答案即为 $\max_{j=0}^{n-1} f[K][j]$。
@@ -220,6 +220,59 @@ func maxVacationDays(flights [][]int, days [][]int) (ans int) {
}
```
+#### TypeScript
+
+```ts
+function maxVacationDays(flights: number[][], days: number[][]): number {
+ const n = flights.length;
+ const K = days[0].length;
+ const inf = Number.NEGATIVE_INFINITY;
+ const f: number[][] = Array.from({ length: K + 1 }, () => Array(n).fill(inf));
+ f[0][0] = 0;
+ for (let k = 1; k <= K; k++) {
+ for (let j = 0; j < n; j++) {
+ f[k][j] = f[k - 1][j];
+ for (let i = 0; i < n; i++) {
+ if (flights[i][j]) {
+ f[k][j] = Math.max(f[k][j], f[k - 1][i]);
+ }
+ }
+ f[k][j] += days[j][k - 1];
+ }
+ }
+ return Math.max(...f[K]);
+}
+```
+
+#### Rust
+
+```rust
+impl Solution {
+ pub fn max_vacation_days(flights: Vec>, days: Vec>) -> i32 {
+ let n = flights.len();
+ let k = days[0].len();
+ let inf = i32::MIN;
+
+ let mut f = vec![vec![inf; n]; k + 1];
+ f[0][0] = 0;
+
+ for step in 1..=k {
+ for j in 0..n {
+ f[step][j] = f[step - 1][j];
+ for i in 0..n {
+ if flights[i][j] == 1 {
+ f[step][j] = f[step][j].max(f[step - 1][i]);
+ }
+ }
+ f[step][j] += days[j][step - 1];
+ }
+ }
+
+ *f[k].iter().max().unwrap()
+ }
+}
+```
+
diff --git a/solution/0500-0599/0568.Maximum Vacation Days/README_EN.md b/solution/0500-0599/0568.Maximum Vacation Days/README_EN.md
index 03606fb98ba45..76fc29b6c73be 100644
--- a/solution/0500-0599/0568.Maximum Vacation Days/README_EN.md
+++ b/solution/0500-0599/0568.Maximum Vacation Days/README_EN.md
@@ -211,6 +211,59 @@ func maxVacationDays(flights [][]int, days [][]int) (ans int) {
}
```
+#### TypeScript
+
+```ts
+function maxVacationDays(flights: number[][], days: number[][]): number {
+ const n = flights.length;
+ const K = days[0].length;
+ const inf = Number.NEGATIVE_INFINITY;
+ const f: number[][] = Array.from({ length: K + 1 }, () => Array(n).fill(inf));
+ f[0][0] = 0;
+ for (let k = 1; k <= K; k++) {
+ for (let j = 0; j < n; j++) {
+ f[k][j] = f[k - 1][j];
+ for (let i = 0; i < n; i++) {
+ if (flights[i][j]) {
+ f[k][j] = Math.max(f[k][j], f[k - 1][i]);
+ }
+ }
+ f[k][j] += days[j][k - 1];
+ }
+ }
+ return Math.max(...f[K]);
+}
+```
+
+#### Rust
+
+```rust
+impl Solution {
+ pub fn max_vacation_days(flights: Vec>, days: Vec>) -> i32 {
+ let n = flights.len();
+ let k = days[0].len();
+ let inf = i32::MIN;
+
+ let mut f = vec![vec![inf; n]; k + 1];
+ f[0][0] = 0;
+
+ for step in 1..=k {
+ for j in 0..n {
+ f[step][j] = f[step - 1][j];
+ for i in 0..n {
+ if flights[i][j] == 1 {
+ f[step][j] = f[step][j].max(f[step - 1][i]);
+ }
+ }
+ f[step][j] += days[j][step - 1];
+ }
+ }
+
+ *f[k].iter().max().unwrap()
+ }
+}
+```
+
diff --git a/solution/0500-0599/0568.Maximum Vacation Days/Solution.rs b/solution/0500-0599/0568.Maximum Vacation Days/Solution.rs
new file mode 100644
index 0000000000000..2483954a7ad16
--- /dev/null
+++ b/solution/0500-0599/0568.Maximum Vacation Days/Solution.rs
@@ -0,0 +1,24 @@
+impl Solution {
+ pub fn max_vacation_days(flights: Vec>, days: Vec>) -> i32 {
+ let n = flights.len();
+ let k = days[0].len();
+ let inf = i32::MIN;
+
+ let mut f = vec![vec![inf; n]; k + 1];
+ f[0][0] = 0;
+
+ for step in 1..=k {
+ for j in 0..n {
+ f[step][j] = f[step - 1][j];
+ for i in 0..n {
+ if flights[i][j] == 1 {
+ f[step][j] = f[step][j].max(f[step - 1][i]);
+ }
+ }
+ f[step][j] += days[j][step - 1];
+ }
+ }
+
+ *f[k].iter().max().unwrap()
+ }
+}
diff --git a/solution/0500-0599/0568.Maximum Vacation Days/Solution.ts b/solution/0500-0599/0568.Maximum Vacation Days/Solution.ts
new file mode 100644
index 0000000000000..23f7d25974af5
--- /dev/null
+++ b/solution/0500-0599/0568.Maximum Vacation Days/Solution.ts
@@ -0,0 +1,19 @@
+function maxVacationDays(flights: number[][], days: number[][]): number {
+ const n = flights.length;
+ const K = days[0].length;
+ const inf = Number.NEGATIVE_INFINITY;
+ const f: number[][] = Array.from({ length: K + 1 }, () => Array(n).fill(inf));
+ f[0][0] = 0;
+ for (let k = 1; k <= K; k++) {
+ for (let j = 0; j < n; j++) {
+ f[k][j] = f[k - 1][j];
+ for (let i = 0; i < n; i++) {
+ if (flights[i][j]) {
+ f[k][j] = Math.max(f[k][j], f[k - 1][i]);
+ }
+ }
+ f[k][j] += days[j][k - 1];
+ }
+ }
+ return Math.max(...f[K]);
+}
diff --git a/solution/0500-0599/0581.Shortest Unsorted Continuous Subarray/README.md b/solution/0500-0599/0581.Shortest Unsorted Continuous Subarray/README.md
index 6d3765e61f6cb..2cf6f98195019 100644
--- a/solution/0500-0599/0581.Shortest Unsorted Continuous Subarray/README.md
+++ b/solution/0500-0599/0581.Shortest Unsorted Continuous Subarray/README.md
@@ -173,32 +173,20 @@ function findUnsortedSubarray(nums: number[]): number {
```rust
impl Solution {
pub fn find_unsorted_subarray(nums: Vec) -> i32 {
- let inf = 1 << 30;
- let n = nums.len();
- let mut l = -1;
- let mut r = -1;
- let mut mi = inf;
- let mut mx = -inf;
-
- for i in 0..n {
- if mx > nums[i] {
- r = i as i32;
- } else {
- mx = nums[i];
- }
-
- if mi < nums[n - i - 1] {
- l = (n - i - 1) as i32;
- } else {
- mi = nums[n - i - 1];
- }
+ let mut arr = nums.clone();
+ arr.sort();
+ let mut l = 0usize;
+ while l < nums.len() && nums[l] == arr[l] {
+ l += 1;
}
-
- if r == -1 {
- 0
- } else {
- r - l + 1
+ if l == nums.len() {
+ return 0;
+ }
+ let mut r = nums.len() - 1;
+ while r > l && nums[r] == arr[r] {
+ r -= 1;
}
+ (r - l + 1) as i32
}
}
```
@@ -340,6 +328,41 @@ function findUnsortedSubarray(nums: number[]): number {
}
```
+#### Rust
+
+```rust
+impl Solution {
+ pub fn find_unsorted_subarray(nums: Vec) -> i32 {
+ let inf = 1 << 30;
+ let n = nums.len();
+ let mut l = -1;
+ let mut r = -1;
+ let mut mi = inf;
+ let mut mx = -inf;
+
+ for i in 0..n {
+ if mx > nums[i] {
+ r = i as i32;
+ } else {
+ mx = nums[i];
+ }
+
+ if mi < nums[n - i - 1] {
+ l = (n - i - 1) as i32;
+ } else {
+ mi = nums[n - i - 1];
+ }
+ }
+
+ if r == -1 {
+ 0
+ } else {
+ r - l + 1
+ }
+ }
+}
+```
+
diff --git a/solution/0500-0599/0581.Shortest Unsorted Continuous Subarray/README_EN.md b/solution/0500-0599/0581.Shortest Unsorted Continuous Subarray/README_EN.md
index 75d9d3a8fd1b0..d05b0d8b85aed 100644
--- a/solution/0500-0599/0581.Shortest Unsorted Continuous Subarray/README_EN.md
+++ b/solution/0500-0599/0581.Shortest Unsorted Continuous Subarray/README_EN.md
@@ -166,32 +166,20 @@ function findUnsortedSubarray(nums: number[]): number {
```rust
impl Solution {
pub fn find_unsorted_subarray(nums: Vec) -> i32 {
- let inf = 1 << 30;
- let n = nums.len();
- let mut l = -1;
- let mut r = -1;
- let mut mi = inf;
- let mut mx = -inf;
-
- for i in 0..n {
- if mx > nums[i] {
- r = i as i32;
- } else {
- mx = nums[i];
- }
-
- if mi < nums[n - i - 1] {
- l = (n - i - 1) as i32;
- } else {
- mi = nums[n - i - 1];
- }
+ let mut arr = nums.clone();
+ arr.sort();
+ let mut l = 0usize;
+ while l < nums.len() && nums[l] == arr[l] {
+ l += 1;
}
-
- if r == -1 {
- 0
- } else {
- r - l + 1
+ if l == nums.len() {
+ return 0;
+ }
+ let mut r = nums.len() - 1;
+ while r > l && nums[r] == arr[r] {
+ r -= 1;
}
+ (r - l + 1) as i32
}
}
```
@@ -333,6 +321,41 @@ function findUnsortedSubarray(nums: number[]): number {
}
```
+#### Rust
+
+```rust
+impl Solution {
+ pub fn find_unsorted_subarray(nums: Vec) -> i32 {
+ let inf = 1 << 30;
+ let n = nums.len();
+ let mut l = -1;
+ let mut r = -1;
+ let mut mi = inf;
+ let mut mx = -inf;
+
+ for i in 0..n {
+ if mx > nums[i] {
+ r = i as i32;
+ } else {
+ mx = nums[i];
+ }
+
+ if mi < nums[n - i - 1] {
+ l = (n - i - 1) as i32;
+ } else {
+ mi = nums[n - i - 1];
+ }
+ }
+
+ if r == -1 {
+ 0
+ } else {
+ r - l + 1
+ }
+ }
+}
+```
+
diff --git a/solution/0500-0599/0581.Shortest Unsorted Continuous Subarray/Solution.rs b/solution/0500-0599/0581.Shortest Unsorted Continuous Subarray/Solution.rs
index bc3aa08117ca2..8e6ec9ada8767 100644
--- a/solution/0500-0599/0581.Shortest Unsorted Continuous Subarray/Solution.rs
+++ b/solution/0500-0599/0581.Shortest Unsorted Continuous Subarray/Solution.rs
@@ -1,30 +1,18 @@
impl Solution {
pub fn find_unsorted_subarray(nums: Vec) -> i32 {
- let inf = 1 << 30;
- let n = nums.len();
- let mut l = -1;
- let mut r = -1;
- let mut mi = inf;
- let mut mx = -inf;
-
- for i in 0..n {
- if mx > nums[i] {
- r = i as i32;
- } else {
- mx = nums[i];
- }
-
- if mi < nums[n - i - 1] {
- l = (n - i - 1) as i32;
- } else {
- mi = nums[n - i - 1];
- }
+ let mut arr = nums.clone();
+ arr.sort();
+ let mut l = 0usize;
+ while l < nums.len() && nums[l] == arr[l] {
+ l += 1;
}
-
- if r == -1 {
- 0
- } else {
- r - l + 1
+ if l == nums.len() {
+ return 0;
}
+ let mut r = nums.len() - 1;
+ while r > l && nums[r] == arr[r] {
+ r -= 1;
+ }
+ (r - l + 1) as i32
}
}
diff --git a/solution/0500-0599/0581.Shortest Unsorted Continuous Subarray/Solution2.rs b/solution/0500-0599/0581.Shortest Unsorted Continuous Subarray/Solution2.rs
new file mode 100644
index 0000000000000..bc3aa08117ca2
--- /dev/null
+++ b/solution/0500-0599/0581.Shortest Unsorted Continuous Subarray/Solution2.rs
@@ -0,0 +1,30 @@
+impl Solution {
+ pub fn find_unsorted_subarray(nums: Vec) -> i32 {
+ let inf = 1 << 30;
+ let n = nums.len();
+ let mut l = -1;
+ let mut r = -1;
+ let mut mi = inf;
+ let mut mx = -inf;
+
+ for i in 0..n {
+ if mx > nums[i] {
+ r = i as i32;
+ } else {
+ mx = nums[i];
+ }
+
+ if mi < nums[n - i - 1] {
+ l = (n - i - 1) as i32;
+ } else {
+ mi = nums[n - i - 1];
+ }
+ }
+
+ if r == -1 {
+ 0
+ } else {
+ r - l + 1
+ }
+ }
+}
diff --git a/solution/0500-0599/0584.Find Customer Referee/README.md b/solution/0500-0599/0584.Find Customer Referee/README.md
index 5c2a099a2d835..fa63febcea511 100644
--- a/solution/0500-0599/0584.Find Customer Referee/README.md
+++ b/solution/0500-0599/0584.Find Customer Referee/README.md
@@ -29,7 +29,12 @@ tags:
在 SQL 中,id 是该表的主键列。
该表的每一行表示一个客户的 id、姓名以及推荐他们的客户的 id。
-
找出那些 没有被id = 2 的客户 推荐 的客户的姓名。
+
找出以下客户的姓名:
+
+
+
被任何id != 2 的用户推荐。
+
没有被 任何用户推荐。
+
以 任意顺序 返回结果表。
diff --git a/solution/0500-0599/0584.Find Customer Referee/README_EN.md b/solution/0500-0599/0584.Find Customer Referee/README_EN.md
index d6810684bb34e..0bd8a5c948aff 100644
--- a/solution/0500-0599/0584.Find Customer Referee/README_EN.md
+++ b/solution/0500-0599/0584.Find Customer Referee/README_EN.md
@@ -32,7 +32,12 @@ Each row of this table indicates the id of a customer, their name, and the id of
-
Find the names of the customer that are not referred by the customer with id = 2.
+
Find the names of the customer that are either:
+
+
+
referred by any customer with id != 2.
+
not referred by any customer.
+
Return the result table in any order.
diff --git a/solution/0500-0599/0594.Longest Harmonious Subsequence/README.md b/solution/0500-0599/0594.Longest Harmonious Subsequence/README.md
index 06b75b6a92e88..faf66f120bb69 100644
--- a/solution/0500-0599/0594.Longest Harmonious Subsequence/README.md
+++ b/solution/0500-0599/0594.Longest Harmonious Subsequence/README.md
@@ -174,6 +174,28 @@ function findLHS(nums: number[]): number {
}
```
+#### Rust
+
+```rust
+use std::collections::HashMap;
+
+impl Solution {
+ pub fn find_lhs(nums: Vec) -> i32 {
+ let mut cnt = HashMap::new();
+ for &x in &nums {
+ *cnt.entry(x).or_insert(0) += 1;
+ }
+ let mut ans = 0;
+ for (&x, &c) in &cnt {
+ if let Some(&y) = cnt.get(&(x + 1)) {
+ ans = ans.max(c + y);
+ }
+ }
+ ans
+ }
+}
+```
+
diff --git a/solution/0500-0599/0594.Longest Harmonious Subsequence/README_EN.md b/solution/0500-0599/0594.Longest Harmonious Subsequence/README_EN.md
index 606ae0f82eff8..58275fbc53a6b 100644
--- a/solution/0500-0599/0594.Longest Harmonious Subsequence/README_EN.md
+++ b/solution/0500-0599/0594.Longest Harmonious Subsequence/README_EN.md
@@ -170,6 +170,28 @@ function findLHS(nums: number[]): number {
}
```
+#### Rust
+
+```rust
+use std::collections::HashMap;
+
+impl Solution {
+ pub fn find_lhs(nums: Vec) -> i32 {
+ let mut cnt = HashMap::new();
+ for &x in &nums {
+ *cnt.entry(x).or_insert(0) += 1;
+ }
+ let mut ans = 0;
+ for (&x, &c) in &cnt {
+ if let Some(&y) = cnt.get(&(x + 1)) {
+ ans = ans.max(c + y);
+ }
+ }
+ ans
+ }
+}
+```
+
diff --git a/solution/0500-0599/0594.Longest Harmonious Subsequence/Solution.rs b/solution/0500-0599/0594.Longest Harmonious Subsequence/Solution.rs
new file mode 100644
index 0000000000000..968a9a460e1b8
--- /dev/null
+++ b/solution/0500-0599/0594.Longest Harmonious Subsequence/Solution.rs
@@ -0,0 +1,17 @@
+use std::collections::HashMap;
+
+impl Solution {
+ pub fn find_lhs(nums: Vec) -> i32 {
+ let mut cnt = HashMap::new();
+ for &x in &nums {
+ *cnt.entry(x).or_insert(0) += 1;
+ }
+ let mut ans = 0;
+ for (&x, &c) in &cnt {
+ if let Some(&y) = cnt.get(&(x + 1)) {
+ ans = ans.max(c + y);
+ }
+ }
+ ans
+ }
+}
diff --git a/solution/0500-0599/0596.Classes More Than 5 Students/README.md b/solution/0500-0599/0596.Classes With at Least 5 Students/README.md
similarity index 90%
rename from solution/0500-0599/0596.Classes More Than 5 Students/README.md
rename to solution/0500-0599/0596.Classes With at Least 5 Students/README.md
index 2f0696381ea24..afc20f4ce53c1 100644
--- a/solution/0500-0599/0596.Classes More Than 5 Students/README.md
+++ b/solution/0500-0599/0596.Classes With at Least 5 Students/README.md
@@ -1,16 +1,16 @@
---
comments: true
difficulty: 简单
-edit_url: https://github.com/doocs/leetcode/edit/main/solution/0500-0599/0596.Classes%20More%20Than%205%20Students/README.md
+edit_url: https://github.com/doocs/leetcode/edit/main/solution/0500-0599/0596.Classes%20With%20at%20Least%205%20Students/README.md
tags:
- 数据库
---
-# [596. 超过 5 名学生的课](https://leetcode.cn/problems/classes-more-than-5-students)
+# [596. 超过 5 名学生的课](https://leetcode.cn/problems/classes-with-at-least-5-students)
-[English Version](/solution/0500-0599/0596.Classes%20More%20Than%205%20Students/README_EN.md)
+[English Version](/solution/0500-0599/0596.Classes%20With%20at%20Least%205%20Students/README_EN.md)
## 题目描述
diff --git a/solution/0500-0599/0596.Classes More Than 5 Students/README_EN.md b/solution/0500-0599/0596.Classes With at Least 5 Students/README_EN.md
similarity index 88%
rename from solution/0500-0599/0596.Classes More Than 5 Students/README_EN.md
rename to solution/0500-0599/0596.Classes With at Least 5 Students/README_EN.md
index e7cb16cd2f521..47ab2c7addb58 100644
--- a/solution/0500-0599/0596.Classes More Than 5 Students/README_EN.md
+++ b/solution/0500-0599/0596.Classes With at Least 5 Students/README_EN.md
@@ -1,16 +1,16 @@
---
comments: true
difficulty: Easy
-edit_url: https://github.com/doocs/leetcode/edit/main/solution/0500-0599/0596.Classes%20More%20Than%205%20Students/README_EN.md
+edit_url: https://github.com/doocs/leetcode/edit/main/solution/0500-0599/0596.Classes%20With%20at%20Least%205%20Students/README_EN.md
tags:
- Database
---
-# [596. Classes More Than 5 Students](https://leetcode.com/problems/classes-more-than-5-students)
+# [596. Classes With at Least 5 Students](https://leetcode.com/problems/classes-with-at-least-5-students)
-[中文文档](/solution/0500-0599/0596.Classes%20More%20Than%205%20Students/README.md)
+[中文文档](/solution/0500-0599/0596.Classes%20With%20at%20Least%205%20Students/README.md)
## Description
diff --git a/solution/0500-0599/0596.Classes More Than 5 Students/Solution.sql b/solution/0500-0599/0596.Classes With at Least 5 Students/Solution.sql
similarity index 100%
rename from solution/0500-0599/0596.Classes More Than 5 Students/Solution.sql
rename to solution/0500-0599/0596.Classes With at Least 5 Students/Solution.sql
diff --git a/solution/0500-0599/0599.Minimum Index Sum of Two Lists/README.md b/solution/0500-0599/0599.Minimum Index Sum of Two Lists/README.md
index 1bd854f37b4b9..ca69de3ea77e5 100644
--- a/solution/0500-0599/0599.Minimum Index Sum of Two Lists/README.md
+++ b/solution/0500-0599/0599.Minimum Index Sum of Two Lists/README.md
@@ -18,9 +18,13 @@ tags:
-
假设 Andy 和 Doris 想在晚餐时选择一家餐厅,并且他们都有一个表示最喜爱餐厅的列表,每个餐厅的名字用字符串表示。
diff --git a/solution/0600-0699/0604.Design Compressed String Iterator/README.md b/solution/0600-0699/0604.Design Compressed String Iterator/README.md
index 9d8866ead6b51..49ed7490b6fa8 100644
--- a/solution/0600-0699/0604.Design Compressed String Iterator/README.md
+++ b/solution/0600-0699/0604.Design Compressed String Iterator/README.md
@@ -267,6 +267,53 @@ func (this *StringIterator) HasNext() bool {
*/
```
+#### TypeScript
+
+```ts
+class StringIterator {
+ private d: [string, number][] = [];
+ private p: number = 0;
+
+ constructor(compressedString: string) {
+ const n = compressedString.length;
+ let i = 0;
+ while (i < n) {
+ const c = compressedString[i];
+ let x = 0;
+ i++;
+ while (i < n && !isNaN(Number(compressedString[i]))) {
+ x = x * 10 + Number(compressedString[i]);
+ i++;
+ }
+ this.d.push([c, x]);
+ }
+ }
+
+ next(): string {
+ if (!this.hasNext()) {
+ return ' ';
+ }
+ const ans = this.d[this.p][0];
+ this.d[this.p][1]--;
+ if (this.d[this.p][1] === 0) {
+ this.p++;
+ }
+ return ans;
+ }
+
+ hasNext(): boolean {
+ return this.p < this.d.length && this.d[this.p][1] > 0;
+ }
+}
+
+/**
+ * Your StringIterator object will be instantiated and called as such:
+ * var obj = new StringIterator(compressedString)
+ * var param_1 = obj.next()
+ * var param_2 = obj.hasNext()
+ */
+```
+
diff --git a/solution/0600-0699/0604.Design Compressed String Iterator/README_EN.md b/solution/0600-0699/0604.Design Compressed String Iterator/README_EN.md
index cc5512a0be612..b5c23f018d70e 100644
--- a/solution/0600-0699/0604.Design Compressed String Iterator/README_EN.md
+++ b/solution/0600-0699/0604.Design Compressed String Iterator/README_EN.md
@@ -67,7 +67,13 @@ stringIterator.hasNext(); // return True
-### Solution 1
+### Solution 1: Parsing and Storing
+
+Parse the `compressedString` into characters $c$ and their corresponding repetition counts $x$, and store them in an array or list $d$. Use $p$ to point to the current character.
+
+Then perform operations in `next` and `hasNext`.
+
+The initialization time complexity is $O(n)$, and the time complexity of the other operations is $O(1)$. Here, $n$ is the length of `compressedString`.
@@ -260,6 +266,53 @@ func (this *StringIterator) HasNext() bool {
*/
```
+#### TypeScript
+
+```ts
+class StringIterator {
+ private d: [string, number][] = [];
+ private p: number = 0;
+
+ constructor(compressedString: string) {
+ const n = compressedString.length;
+ let i = 0;
+ while (i < n) {
+ const c = compressedString[i];
+ let x = 0;
+ i++;
+ while (i < n && !isNaN(Number(compressedString[i]))) {
+ x = x * 10 + Number(compressedString[i]);
+ i++;
+ }
+ this.d.push([c, x]);
+ }
+ }
+
+ next(): string {
+ if (!this.hasNext()) {
+ return ' ';
+ }
+ const ans = this.d[this.p][0];
+ this.d[this.p][1]--;
+ if (this.d[this.p][1] === 0) {
+ this.p++;
+ }
+ return ans;
+ }
+
+ hasNext(): boolean {
+ return this.p < this.d.length && this.d[this.p][1] > 0;
+ }
+}
+
+/**
+ * Your StringIterator object will be instantiated and called as such:
+ * var obj = new StringIterator(compressedString)
+ * var param_1 = obj.next()
+ * var param_2 = obj.hasNext()
+ */
+```
+
diff --git a/solution/0600-0699/0604.Design Compressed String Iterator/Solution.ts b/solution/0600-0699/0604.Design Compressed String Iterator/Solution.ts
new file mode 100644
index 0000000000000..6313052a68374
--- /dev/null
+++ b/solution/0600-0699/0604.Design Compressed String Iterator/Solution.ts
@@ -0,0 +1,42 @@
+class StringIterator {
+ private d: [string, number][] = [];
+ private p: number = 0;
+
+ constructor(compressedString: string) {
+ const n = compressedString.length;
+ let i = 0;
+ while (i < n) {
+ const c = compressedString[i];
+ let x = 0;
+ i++;
+ while (i < n && !isNaN(Number(compressedString[i]))) {
+ x = x * 10 + Number(compressedString[i]);
+ i++;
+ }
+ this.d.push([c, x]);
+ }
+ }
+
+ next(): string {
+ if (!this.hasNext()) {
+ return ' ';
+ }
+ const ans = this.d[this.p][0];
+ this.d[this.p][1]--;
+ if (this.d[this.p][1] === 0) {
+ this.p++;
+ }
+ return ans;
+ }
+
+ hasNext(): boolean {
+ return this.p < this.d.length && this.d[this.p][1] > 0;
+ }
+}
+
+/**
+ * Your StringIterator object will be instantiated and called as such:
+ * var obj = new StringIterator(compressedString)
+ * var param_1 = obj.next()
+ * var param_2 = obj.hasNext()
+ */
diff --git a/solution/0600-0699/0630.Course Schedule III/README.md b/solution/0600-0699/0630.Course Schedule III/README.md
index 6375a17781381..0892c7c3ea024 100644
--- a/solution/0600-0699/0630.Course Schedule III/README.md
+++ b/solution/0600-0699/0630.Course Schedule III/README.md
@@ -179,13 +179,13 @@ func (h *hp) pop() int { return heap.Pop(h).(int) }
```ts
function scheduleCourse(courses: number[][]): number {
courses.sort((a, b) => a[1] - b[1]);
- const pq = new MaxPriorityQueue();
+ const pq = new MaxPriorityQueue();
let s = 0;
for (const [duration, last] of courses) {
pq.enqueue(duration);
s += duration;
while (s > last) {
- s -= pq.dequeue().element;
+ s -= pq.dequeue();
}
}
return pq.size();
diff --git a/solution/0600-0699/0630.Course Schedule III/README_EN.md b/solution/0600-0699/0630.Course Schedule III/README_EN.md
index 635e4695af275..c62bec88ced90 100644
--- a/solution/0600-0699/0630.Course Schedule III/README_EN.md
+++ b/solution/0600-0699/0630.Course Schedule III/README_EN.md
@@ -170,13 +170,13 @@ func (h *hp) pop() int { return heap.Pop(h).(int) }
```ts
function scheduleCourse(courses: number[][]): number {
courses.sort((a, b) => a[1] - b[1]);
- const pq = new MaxPriorityQueue();
+ const pq = new MaxPriorityQueue();
let s = 0;
for (const [duration, last] of courses) {
pq.enqueue(duration);
s += duration;
while (s > last) {
- s -= pq.dequeue().element;
+ s -= pq.dequeue();
}
}
return pq.size();
diff --git a/solution/0600-0699/0630.Course Schedule III/Solution.ts b/solution/0600-0699/0630.Course Schedule III/Solution.ts
index cf53fa353f7fb..fa2048b5b649b 100644
--- a/solution/0600-0699/0630.Course Schedule III/Solution.ts
+++ b/solution/0600-0699/0630.Course Schedule III/Solution.ts
@@ -1,12 +1,12 @@
function scheduleCourse(courses: number[][]): number {
courses.sort((a, b) => a[1] - b[1]);
- const pq = new MaxPriorityQueue();
+ const pq = new MaxPriorityQueue();
let s = 0;
for (const [duration, last] of courses) {
pq.enqueue(duration);
s += duration;
while (s > last) {
- s -= pq.dequeue().element;
+ s -= pq.dequeue();
}
}
return pq.size();
diff --git a/solution/0600-0699/0631.Design Excel Sum Formula/README.md b/solution/0600-0699/0631.Design Excel Sum Formula/README.md
index 5559a4feeaeec..fe1c6cd51ca57 100644
--- a/solution/0600-0699/0631.Design Excel Sum Formula/README.md
+++ b/solution/0600-0699/0631.Design Excel Sum Formula/README.md
@@ -7,6 +7,8 @@ tags:
- 设计
- 拓扑排序
- 数组
+ - 哈希表
+ - 字符串
- 矩阵
---
diff --git a/solution/0600-0699/0631.Design Excel Sum Formula/README_EN.md b/solution/0600-0699/0631.Design Excel Sum Formula/README_EN.md
index cd7ce68ca40f6..6c32824892c92 100644
--- a/solution/0600-0699/0631.Design Excel Sum Formula/README_EN.md
+++ b/solution/0600-0699/0631.Design Excel Sum Formula/README_EN.md
@@ -7,6 +7,8 @@ tags:
- Design
- Topological Sort
- Array
+ - Hash Table
+ - String
- Matrix
---
diff --git a/solution/0600-0699/0636.Exclusive Time of Functions/README.md b/solution/0600-0699/0636.Exclusive Time of Functions/README.md
index 9dc839b951335..7f5e3268f6a69 100644
--- a/solution/0600-0699/0636.Exclusive Time of Functions/README.md
+++ b/solution/0600-0699/0636.Exclusive Time of Functions/README.md
@@ -73,7 +73,7 @@ tags:
1 <= n <= 100
-
1 <= logs.length <= 500
+
2 <= logs.length <= 500
0 <= function_id < n
0 <= timestamp <= 109
两个开始事件不会在同一时间戳发生
diff --git a/solution/0600-0699/0636.Exclusive Time of Functions/README_EN.md b/solution/0600-0699/0636.Exclusive Time of Functions/README_EN.md
index 86ba7c74a8966..c3a6873eb79c4 100644
--- a/solution/0600-0699/0636.Exclusive Time of Functions/README_EN.md
+++ b/solution/0600-0699/0636.Exclusive Time of Functions/README_EN.md
@@ -73,7 +73,7 @@ So function 0 spends 2 + 4 + 1 = 7 units of total time executing, and function 1
1 <= n <= 100
-
1 <= logs.length <= 500
+
2 <= logs.length <= 500
0 <= function_id < n
0 <= timestamp <= 109
No two start events will happen at the same timestamp.