表:Users
@@ -57,11 +55,9 @@ users_id 是这张表的主键(具有唯一值的列)。
banned 是一个表示用户是否被禁止的枚举类型,枚举成员为 (‘Yes’, ‘No’) 。
-
-
取消率 的计算方式如下:(被司机或乘客取消的非禁止用户生成的订单数量) / (非禁止用户生成的订单总数)。
-
编写解决方案找出 "2013-10-01"
至 "2013-10-03"
期间非禁止用户(乘客和司机都必须未被禁止)的取消率。非禁止用户即 banned 为 No 的用户,禁止用户即 banned 为 Yes 的用户。其中取消率 Cancellation Rate
需要四舍五入保留 两位小数 。
+
编写解决方案找出 "2013-10-01"
至 "2013-10-03"
期间有 至少 一次行程的非禁止用户(乘客和司机都必须未被禁止)的 取消率。非禁止用户即 banned 为 No 的用户,禁止用户即 banned 为 Yes 的用户。其中取消率 Cancellation Rate
需要四舍五入保留 两位小数 。
返回结果表中的数据 无顺序要求 。
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:
-
给你一个整数数组 citations
,其中 citations[i]
表示研究者的第 i
篇论文被引用的次数,citations
已经按照 升序排列 。计算并返回该研究者的 h 指数。
+
给你一个整数数组 citations
,其中 citations[i]
表示研究者的第 i
篇论文被引用的次数,citations
已经按照 非降序排列 。计算并返回该研究者的 h 指数。
h 指数的定义:h 代表“高引用次数”(high citations),一名科研人员的 h
指数是指他(她)的 (n
篇论文中)至少 有 h
篇论文分别被引用了至少 h
次。
diff --git a/solution/0200-0299/0275.H-Index II/README_EN.md b/solution/0200-0299/0275.H-Index II/README_EN.md
index e8247fe65c36e..bd538b6782e05 100644
--- a/solution/0200-0299/0275.H-Index II/README_EN.md
+++ b/solution/0200-0299/0275.H-Index II/README_EN.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/0278.First Bad Version/README.md b/solution/0200-0299/0278.First Bad Version/README.md
index 19c1f9bc17397..4bf3178b186a3 100644
--- a/solution/0200-0299/0278.First Bad Version/README.md
+++ b/solution/0200-0299/0278.First Bad Version/README.md
@@ -57,7 +57,15 @@ tags:
-### 方法一
+### 方法一:二分查找
+
+我们定义二分查找的左边界 $l = 1$,右边界 $r = n$。
+
+当 $l < r$ 时,我们计算中间位置 $\textit{mid} = \left\lfloor \frac{l + r}{2} \right\rfloor$,然后调用 `isBadVersion(mid)` 接口,如果返回 $\textit{true}$,则说明第一个错误的版本在 $[l, \textit{mid}]$ 之间,我们令 $r = \textit{mid}$;否则第一个错误的版本在 $[\textit{mid} + 1, r]$ 之间,我们令 $l = \textit{mid} + 1$。
+
+最终返回 $l$ 即可。
+
+时间复杂度 $O(\log n)$,空间复杂度 $O(1)$。
@@ -65,25 +73,19 @@ tags:
```python
# The isBadVersion API is already defined for you.
-# @param version, an integer
-# @return an integer
-# def isBadVersion(version):
+# def isBadVersion(version: int) -> bool:
class Solution:
- def firstBadVersion(self, n):
- """
- :type n: int
- :rtype: int
- """
- left, right = 1, n
- while left < right:
- mid = (left + right) >> 1
+ def firstBadVersion(self, n: int) -> int:
+ l, r = 1, n
+ while l < r:
+ mid = (l + r) >> 1
if isBadVersion(mid):
- right = mid
+ r = mid
else:
- left = mid + 1
- return left
+ l = mid + 1
+ return l
```
#### Java
@@ -94,16 +96,16 @@ class Solution:
public class Solution extends VersionControl {
public int firstBadVersion(int n) {
- int left = 1, right = n;
- while (left < right) {
- int mid = (left + right) >>> 1;
+ int l = 1, r = n;
+ while (l < r) {
+ int mid = (l + r) >>> 1;
if (isBadVersion(mid)) {
- right = mid;
+ r = mid;
} else {
- left = mid + 1;
+ l = mid + 1;
}
}
- return left;
+ return l;
}
}
```
@@ -117,16 +119,16 @@ public class Solution extends VersionControl {
class Solution {
public:
int firstBadVersion(int n) {
- int left = 1, right = n;
- while (left < right) {
- int mid = left + ((right - left) >> 1);
+ int l = 1, r = n;
+ while (l < r) {
+ int mid = l + (r - l) / 2;
if (isBadVersion(mid)) {
- right = mid;
+ r = mid;
} else {
- left = mid + 1;
+ l = mid + 1;
}
}
- return left;
+ return l;
}
};
```
@@ -143,19 +145,45 @@ public:
*/
func firstBadVersion(n int) int {
- left, right := 1, n
- for left < right {
- mid := (left + right) >> 1
+ l, r := 1, n
+ for l < r {
+ mid := (l + r) >> 1
if isBadVersion(mid) {
- right = mid
+ r = mid
} else {
- left = mid + 1
+ l = mid + 1
}
}
- return left
+ return l
}
```
+#### TypeScript
+
+```ts
+/**
+ * The knows API is defined in the parent class Relation.
+ * isBadVersion(version: number): boolean {
+ * ...
+ * };
+ */
+
+var solution = function (isBadVersion: any) {
+ return function (n: number): number {
+ let [l, r] = [1, n];
+ while (l < r) {
+ const mid = (l + r) >>> 1;
+ if (isBadVersion(mid)) {
+ r = mid;
+ } else {
+ l = mid + 1;
+ }
+ }
+ return l;
+ };
+};
+```
+
#### Rust
```rust
@@ -165,17 +193,16 @@ func firstBadVersion(n int) int {
impl Solution {
pub fn first_bad_version(&self, n: i32) -> i32 {
- let mut left = 1;
- let mut right = n;
- while left < right {
- let mid = left + (right - left) / 2;
+ let (mut l, mut r) = (1, n);
+ while l < r {
+ let mid = l + (r - l) / 2;
if self.isBadVersion(mid) {
- right = mid;
+ r = mid;
} else {
- left = mid + 1;
+ l = mid + 1;
}
}
- left
+ l
}
}
```
@@ -203,17 +230,16 @@ var solution = function (isBadVersion) {
* @return {integer} The first bad version
*/
return function (n) {
- let left = 1;
- let right = n;
- while (left < right) {
- const mid = (left + right) >>> 1;
+ let [l, r] = [1, n];
+ while (l < r) {
+ const mid = (l + r) >>> 1;
if (isBadVersion(mid)) {
- right = mid;
+ r = mid;
} else {
- left = mid + 1;
+ l = mid + 1;
}
}
- return left;
+ return l;
};
};
```
diff --git a/solution/0200-0299/0278.First Bad Version/README_EN.md b/solution/0200-0299/0278.First Bad Version/README_EN.md
index 5608efe4d2f33..45c6becbac802 100644
--- a/solution/0200-0299/0278.First Bad Version/README_EN.md
+++ b/solution/0200-0299/0278.First Bad Version/README_EN.md
@@ -56,7 +56,15 @@ Then 4 is the first bad version.
-### Solution 1
+### Solution 1: Binary Search
+
+We define the left boundary of the binary search as $l = 1$ and the right boundary as $r = n$.
+
+While $l < r$, we calculate the middle position $\textit{mid} = \left\lfloor \frac{l + r}{2} \right\rfloor$, then call the `isBadVersion(mid)` API. If it returns $\textit{true}$, it means the first bad version is between $[l, \textit{mid}]$, so we set $r = \textit{mid}$; otherwise, the first bad version is between $[\textit{mid} + 1, r]$, so we set $l = \textit{mid} + 1$.
+
+Finally, we return $l$.
+
+The time complexity is $O(\log n)$, and the space complexity is $O(1)$.
@@ -64,25 +72,19 @@ Then 4 is the first bad version.
```python
# The isBadVersion API is already defined for you.
-# @param version, an integer
-# @return an integer
-# def isBadVersion(version):
+# def isBadVersion(version: int) -> bool:
class Solution:
- def firstBadVersion(self, n):
- """
- :type n: int
- :rtype: int
- """
- left, right = 1, n
- while left < right:
- mid = (left + right) >> 1
+ def firstBadVersion(self, n: int) -> int:
+ l, r = 1, n
+ while l < r:
+ mid = (l + r) >> 1
if isBadVersion(mid):
- right = mid
+ r = mid
else:
- left = mid + 1
- return left
+ l = mid + 1
+ return l
```
#### Java
@@ -93,16 +95,16 @@ class Solution:
public class Solution extends VersionControl {
public int firstBadVersion(int n) {
- int left = 1, right = n;
- while (left < right) {
- int mid = (left + right) >>> 1;
+ int l = 1, r = n;
+ while (l < r) {
+ int mid = (l + r) >>> 1;
if (isBadVersion(mid)) {
- right = mid;
+ r = mid;
} else {
- left = mid + 1;
+ l = mid + 1;
}
}
- return left;
+ return l;
}
}
```
@@ -116,16 +118,16 @@ public class Solution extends VersionControl {
class Solution {
public:
int firstBadVersion(int n) {
- int left = 1, right = n;
- while (left < right) {
- int mid = left + ((right - left) >> 1);
+ int l = 1, r = n;
+ while (l < r) {
+ int mid = l + (r - l) / 2;
if (isBadVersion(mid)) {
- right = mid;
+ r = mid;
} else {
- left = mid + 1;
+ l = mid + 1;
}
}
- return left;
+ return l;
}
};
```
@@ -142,19 +144,45 @@ public:
*/
func firstBadVersion(n int) int {
- left, right := 1, n
- for left < right {
- mid := (left + right) >> 1
+ l, r := 1, n
+ for l < r {
+ mid := (l + r) >> 1
if isBadVersion(mid) {
- right = mid
+ r = mid
} else {
- left = mid + 1
+ l = mid + 1
}
}
- return left
+ return l
}
```
+#### TypeScript
+
+```ts
+/**
+ * The knows API is defined in the parent class Relation.
+ * isBadVersion(version: number): boolean {
+ * ...
+ * };
+ */
+
+var solution = function (isBadVersion: any) {
+ return function (n: number): number {
+ let [l, r] = [1, n];
+ while (l < r) {
+ const mid = (l + r) >>> 1;
+ if (isBadVersion(mid)) {
+ r = mid;
+ } else {
+ l = mid + 1;
+ }
+ }
+ return l;
+ };
+};
+```
+
#### Rust
```rust
@@ -164,17 +192,16 @@ func firstBadVersion(n int) int {
impl Solution {
pub fn first_bad_version(&self, n: i32) -> i32 {
- let mut left = 1;
- let mut right = n;
- while left < right {
- let mid = left + (right - left) / 2;
+ let (mut l, mut r) = (1, n);
+ while l < r {
+ let mid = l + (r - l) / 2;
if self.isBadVersion(mid) {
- right = mid;
+ r = mid;
} else {
- left = mid + 1;
+ l = mid + 1;
}
}
- left
+ l
}
}
```
@@ -202,17 +229,16 @@ var solution = function (isBadVersion) {
* @return {integer} The first bad version
*/
return function (n) {
- let left = 1;
- let right = n;
- while (left < right) {
- const mid = (left + right) >>> 1;
+ let [l, r] = [1, n];
+ while (l < r) {
+ const mid = (l + r) >>> 1;
if (isBadVersion(mid)) {
- right = mid;
+ r = mid;
} else {
- left = mid + 1;
+ l = mid + 1;
}
}
- return left;
+ return l;
};
};
```
diff --git a/solution/0200-0299/0278.First Bad Version/Solution.cpp b/solution/0200-0299/0278.First Bad Version/Solution.cpp
index 975f5fdb508dd..5536140dafb6b 100644
--- a/solution/0200-0299/0278.First Bad Version/Solution.cpp
+++ b/solution/0200-0299/0278.First Bad Version/Solution.cpp
@@ -4,15 +4,15 @@
class Solution {
public:
int firstBadVersion(int n) {
- int left = 1, right = n;
- while (left < right) {
- int mid = left + ((right - left) >> 1);
+ int l = 1, r = n;
+ while (l < r) {
+ int mid = l + (r - l) / 2;
if (isBadVersion(mid)) {
- right = mid;
+ r = mid;
} else {
- left = mid + 1;
+ l = mid + 1;
}
}
- return left;
+ return l;
}
-};
\ No newline at end of file
+};
diff --git a/solution/0200-0299/0278.First Bad Version/Solution.go b/solution/0200-0299/0278.First Bad Version/Solution.go
index 6cfe9c4ee4c50..579b225670465 100644
--- a/solution/0200-0299/0278.First Bad Version/Solution.go
+++ b/solution/0200-0299/0278.First Bad Version/Solution.go
@@ -7,14 +7,14 @@
*/
func firstBadVersion(n int) int {
- left, right := 1, n
- for left < right {
- mid := (left + right) >> 1
+ l, r := 1, n
+ for l < r {
+ mid := (l + r) >> 1
if isBadVersion(mid) {
- right = mid
+ r = mid
} else {
- left = mid + 1
+ l = mid + 1
}
}
- return left
-}
\ No newline at end of file
+ return l
+}
diff --git a/solution/0200-0299/0278.First Bad Version/Solution.java b/solution/0200-0299/0278.First Bad Version/Solution.java
index 5039dd4fb8a95..a205ba020c22c 100644
--- a/solution/0200-0299/0278.First Bad Version/Solution.java
+++ b/solution/0200-0299/0278.First Bad Version/Solution.java
@@ -3,15 +3,15 @@
public class Solution extends VersionControl {
public int firstBadVersion(int n) {
- int left = 1, right = n;
- while (left < right) {
- int mid = (left + right) >>> 1;
+ int l = 1, r = n;
+ while (l < r) {
+ int mid = (l + r) >>> 1;
if (isBadVersion(mid)) {
- right = mid;
+ r = mid;
} else {
- left = mid + 1;
+ l = mid + 1;
}
}
- return left;
+ return l;
}
-}
\ No newline at end of file
+}
diff --git a/solution/0200-0299/0278.First Bad Version/Solution.js b/solution/0200-0299/0278.First Bad Version/Solution.js
index 9258a94af6da2..76b3b3dcc548d 100644
--- a/solution/0200-0299/0278.First Bad Version/Solution.js
+++ b/solution/0200-0299/0278.First Bad Version/Solution.js
@@ -18,16 +18,15 @@ var solution = function (isBadVersion) {
* @return {integer} The first bad version
*/
return function (n) {
- let left = 1;
- let right = n;
- while (left < right) {
- const mid = (left + right) >>> 1;
+ let [l, r] = [1, n];
+ while (l < r) {
+ const mid = (l + r) >>> 1;
if (isBadVersion(mid)) {
- right = mid;
+ r = mid;
} else {
- left = mid + 1;
+ l = mid + 1;
}
}
- return left;
+ return l;
};
};
diff --git a/solution/0200-0299/0278.First Bad Version/Solution.py b/solution/0200-0299/0278.First Bad Version/Solution.py
index 8f00dbe67f9cf..74ed74886e2c1 100644
--- a/solution/0200-0299/0278.First Bad Version/Solution.py
+++ b/solution/0200-0299/0278.First Bad Version/Solution.py
@@ -1,20 +1,14 @@
# The isBadVersion API is already defined for you.
-# @param version, an integer
-# @return an integer
-# def isBadVersion(version):
+# def isBadVersion(version: int) -> bool:
class Solution:
- def firstBadVersion(self, n):
- """
- :type n: int
- :rtype: int
- """
- left, right = 1, n
- while left < right:
- mid = (left + right) >> 1
+ def firstBadVersion(self, n: int) -> int:
+ l, r = 1, n
+ while l < r:
+ mid = (l + r) >> 1
if isBadVersion(mid):
- right = mid
+ r = mid
else:
- left = mid + 1
- return left
+ l = mid + 1
+ return l
diff --git a/solution/0200-0299/0278.First Bad Version/Solution.rs b/solution/0200-0299/0278.First Bad Version/Solution.rs
index 42411a4e2a095..97fc16ce989d7 100644
--- a/solution/0200-0299/0278.First Bad Version/Solution.rs
+++ b/solution/0200-0299/0278.First Bad Version/Solution.rs
@@ -4,16 +4,15 @@
impl Solution {
pub fn first_bad_version(&self, n: i32) -> i32 {
- let mut left = 1;
- let mut right = n;
- while left < right {
- let mid = left + (right - left) / 2;
+ let (mut l, mut r) = (1, n);
+ while l < r {
+ let mid = l + (r - l) / 2;
if self.isBadVersion(mid) {
- right = mid;
+ r = mid;
} else {
- left = mid + 1;
+ l = mid + 1;
}
}
- left
+ l
}
}
diff --git a/solution/0200-0299/0278.First Bad Version/Solution.ts b/solution/0200-0299/0278.First Bad Version/Solution.ts
new file mode 100644
index 0000000000000..6a6001924f16d
--- /dev/null
+++ b/solution/0200-0299/0278.First Bad Version/Solution.ts
@@ -0,0 +1,21 @@
+/**
+ * The knows API is defined in the parent class Relation.
+ * isBadVersion(version: number): boolean {
+ * ...
+ * };
+ */
+
+var solution = function (isBadVersion: any) {
+ return function (n: number): number {
+ let [l, r] = [1, n];
+ while (l < r) {
+ const mid = (l + r) >>> 1;
+ if (isBadVersion(mid)) {
+ r = mid;
+ } else {
+ l = mid + 1;
+ }
+ }
+ return l;
+ };
+};
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/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:
总旅行距离 是朋友们家到聚会地点的距离之和。
-
使用 曼哈顿距离 计算距离,其中距离 (p1, p2) = |p2.x - p1.x | + | p2.y - p1.y |
。
-
示例 1:
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/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/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/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/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-
示例 3:
-输入:sentence = ["I", "had", "apple", "pie"], rows = 4, cols = 5
+输入:sentence = ["i", "had", "apple", "pie"], rows = 4, cols = 5
输出:1
解释:
-I-had
+i-had
apple
-pie-I
+pie-i
had--
字符 '-' 表示屏幕上的一个空白位置。
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/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/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:
- 全部字母都是大写,比如
"USA"
。
- - 单词中所有字母都不是大写,比如
"leetcode"
。
- - 如果单词不只含有一个字母,只有首字母大写, 比如
"Google"
。
+ - 所有字母都不是大写,比如
"leetcode"
。
+ - 只有首字母大写, 比如
"Google"
。
给你一个字符串 word
。如果大写用法正确,返回 true
;否则,返回 false
。
diff --git a/solution/0500-0599/0525.Contiguous Array/README.md b/solution/0500-0599/0525.Contiguous Array/README.md
index 0e49c1a1f4c82..9b170bc8e884f 100644
--- a/solution/0500-0599/0525.Contiguous Array/README.md
+++ b/solution/0500-0599/0525.Contiguous Array/README.md
@@ -20,28 +20,35 @@ tags:
给定一个二进制数组 nums
, 找到含有相同数量的 0
和 1
的最长连续子数组,并返回该子数组的长度。
-
+
-示例 1:
+示例 1:
-输入: nums = [0,1]
-输出: 2
-说明: [0, 1] 是具有相同数量 0 和 1 的最长连续子数组。
+输入:nums = [0,1]
+输出:2
+说明:[0, 1] 是具有相同数量 0 和 1 的最长连续子数组。
-示例 2:
+示例 2:
-输入: nums = [0,1,0]
-输出: 2
-说明: [0, 1] (或 [1, 0]) 是具有相同数量0和1的最长连续子数组。
+输入:nums = [0,1,0]
+输出:2
+说明:[0, 1] (或 [1, 0]) 是具有相同数量 0 和 1 的最长连续子数组。
-
+示例 3:
+
+
+输入:nums = [0,1,1,1,1,1,0,0,0]
+输出:6
+解释:[1,1,1,0,0,0] 是具有相同数量 0 和 1 的最长连续子数组。
+
+
提示:
- 1 <= nums.length <= 105
+ 1 <= nums.length <= 105
nums[i]
不是 0
就是 1
diff --git a/solution/0500-0599/0525.Contiguous Array/README_EN.md b/solution/0500-0599/0525.Contiguous Array/README_EN.md
index 8dfeb6693c9ae..1377e34ef50fa 100644
--- a/solution/0500-0599/0525.Contiguous Array/README_EN.md
+++ b/solution/0500-0599/0525.Contiguous Array/README_EN.md
@@ -37,6 +37,14 @@ tags:
Explanation: [0, 1] (or [1, 0]) is a longest contiguous subarray with equal number of 0 and 1.
+Example 3:
+
+
+Input: nums = [0,1,1,1,1,1,0,0,0]
+Output: 6
+Explanation: [1,1,1,0,0,0] is the longest contiguous subarray with equal number of 0 and 1.
+
+
Constraints:
diff --git a/solution/0500-0599/0532.K-diff Pairs in an Array/README.md b/solution/0500-0599/0532.K-diff Pairs in an Array/README.md
index 6ec116976d429..1053a06cc32ac 100644
--- a/solution/0500-0599/0532.K-diff Pairs in an Array/README.md
+++ b/solution/0500-0599/0532.K-diff Pairs in an Array/README.md
@@ -77,11 +77,13 @@ tags:
### 方法一:哈希表
-由于 $k$ 是一个定值,因此用哈希表 $ans$ 记录数对的较小值,就能够确定较大的值。最后返回 ans 的大小作为答案。
+由于 $k$ 是一个定值,我们可以用一个哈希表 $\textit{ans}$ 记录数对的较小值,就能够确定较大的值。最后返回 $\textit{ans}$ 的大小作为答案。
-遍历数组 $nums$,当前遍历到的数 $nums[j]$,我们记为 $v$,用哈希表 $vis$ 记录此前遍历到的所有数字。若 $v-k$ 在 $vis$ 中,则将 $v-k$ 添加至 $ans$;若 $v+k$ 在 $vis$ 中,则将 $v$ 添加至 $ans$。
+遍历数组 $\textit{nums}$,当前遍历到的数 $x$,我们用哈希表 $\textit{vis}$ 记录此前遍历到的所有数字。若 $x-k$ 在 $\textit{vis}$ 中,则将 $x-k$ 添加至 $\textit{ans}$;若 $x+k$ 在 $\textit{vis}$ 中,则将 $x$ 添加至 $\textit{ans}$。然后我们将 $x$ 添加至 $\textit{vis}$。继续遍历数组 $\textit{nums}$ 直至遍历结束。
-时间复杂度 $O(n)$,其中 $n$ 表示数组 $nums$ 的长度。
+最后返回 $\textit{ans}$ 的大小作为答案。
+
+时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $\textit{nums}$ 的长度。
@@ -90,13 +92,14 @@ tags:
```python
class Solution:
def findPairs(self, nums: List[int], k: int) -> int:
- vis, ans = set(), set()
- for v in nums:
- if v - k in vis:
- ans.add(v - k)
- if v + k in vis:
- ans.add(v)
- vis.add(v)
+ ans = set()
+ vis = set()
+ for x in nums:
+ if x - k in vis:
+ ans.add(x - k)
+ if x + k in vis:
+ ans.add(x)
+ vis.add(x)
return len(ans)
```
@@ -105,16 +108,16 @@ class Solution:
```java
class Solution {
public int findPairs(int[] nums, int k) {
- Set vis = new HashSet<>();
Set ans = new HashSet<>();
- for (int v : nums) {
- if (vis.contains(v - k)) {
- ans.add(v - k);
+ Set vis = new HashSet<>();
+ for (int x : nums) {
+ if (vis.contains(x - k)) {
+ ans.add(x - k);
}
- if (vis.contains(v + k)) {
- ans.add(v);
+ if (vis.contains(x + k)) {
+ ans.add(x);
}
- vis.add(v);
+ vis.add(x);
}
return ans.size();
}
@@ -127,12 +130,15 @@ class Solution {
class Solution {
public:
int findPairs(vector& nums, int k) {
- unordered_set vis;
- unordered_set ans;
- for (int& v : nums) {
- if (vis.count(v - k)) ans.insert(v - k);
- if (vis.count(v + k)) ans.insert(v);
- vis.insert(v);
+ unordered_set ans, vis;
+ for (int x : nums) {
+ if (vis.count(x - k)) {
+ ans.insert(x - k);
+ }
+ if (vis.count(x + k)) {
+ ans.insert(x);
+ }
+ vis.insert(x);
}
return ans.size();
}
@@ -143,52 +149,61 @@ public:
```go
func findPairs(nums []int, k int) int {
- vis := map[int]bool{}
- ans := map[int]bool{}
- for _, v := range nums {
- if vis[v-k] {
- ans[v-k] = true
+ ans := make(map[int]struct{})
+ vis := make(map[int]struct{})
+
+ for _, x := range nums {
+ if _, ok := vis[x-k]; ok {
+ ans[x-k] = struct{}{}
}
- if vis[v+k] {
- ans[v] = true
+ if _, ok := vis[x+k]; ok {
+ ans[x] = struct{}{}
}
- vis[v] = true
+ vis[x] = struct{}{}
}
return len(ans)
}
```
+#### TypeScript
+
+```ts
+function findPairs(nums: number[], k: number): number {
+ const ans = new Set();
+ const vis = new Set();
+ for (const x of nums) {
+ if (vis.has(x - k)) {
+ ans.add(x - k);
+ }
+ if (vis.has(x + k)) {
+ ans.add(x);
+ }
+ vis.add(x);
+ }
+ return ans.size;
+}
+```
+
#### Rust
```rust
+use std::collections::HashSet;
+
impl Solution {
- pub fn find_pairs(mut nums: Vec