Skip to content

Commit 9a8c3cb

Browse files
authored
Merge branch 'doocs:main' into main
2 parents d60575e + 9bb6d44 commit 9a8c3cb

File tree

27 files changed

+683
-379
lines changed

27 files changed

+683
-379
lines changed

solution/0600-0699/0633.Sum of Square Numbers/README.md

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,11 @@
3737

3838
## 解法
3939

40-
### 方法一
40+
### 方法一:数学 + 双指针
41+
42+
我们可以使用双指针的方法来解决这个问题,定义两个指针 $a$ 和 $b$,分别指向 $0$ 和 $\sqrt{c}$。在每一步中,我们会计算 $s = a^2 + b^2$ 的值,然后比较 $s$ 与 $c$ 的大小。如果 $s = c$,我们就找到了两个整数 $a$ 和 $b$,使得 $a^2 + b^2 = c$。如果 $s < c$,我们将 $a$ 的值增加 $1$,如果 $s > c$,我们将 $b$ 的值减小 $1$。我们不断进行这个过程直到找到答案,或者 $a$ 的值大于 $b$ 的值,返回 `false`
43+
44+
时间复杂度 $O(\sqrt{c})$,其中 $c$ 是给定的非负整数。空间复杂度 $O(1)$。
4145

4246
<!-- tabs:start -->
4347

@@ -80,14 +84,17 @@ class Solution {
8084
class Solution {
8185
public:
8286
bool judgeSquareSum(int c) {
83-
long a = 0, b = (long) sqrt(c);
87+
long long a = 0, b = sqrt(c);
8488
while (a <= b) {
85-
long s = a * a + b * b;
86-
if (s == c) return true;
87-
if (s < c)
89+
long long s = a * a + b * b;
90+
if (s == c) {
91+
return true;
92+
}
93+
if (s < c) {
8894
++a;
89-
else
95+
} else {
9096
--b;
97+
}
9198
}
9299
return false;
93100
}
@@ -114,12 +121,13 @@ func judgeSquareSum(c int) bool {
114121

115122
```ts
116123
function judgeSquareSum(c: number): boolean {
117-
let a = 0,
118-
b = Math.floor(Math.sqrt(c));
124+
let [a, b] = [0, Math.floor(Math.sqrt(c))];
119125
while (a <= b) {
120-
let sum = a ** 2 + b ** 2;
121-
if (sum == c) return true;
122-
if (sum < c) {
126+
const s = a * a + b * b;
127+
if (s === c) {
128+
return true;
129+
}
130+
if (s < c) {
123131
++a;
124132
} else {
125133
--b;
@@ -131,22 +139,22 @@ function judgeSquareSum(c: number): boolean {
131139

132140
```rust
133141
use std::cmp::Ordering;
142+
134143
impl Solution {
135144
pub fn judge_square_sum(c: i32) -> bool {
136-
let c = c as i64;
137-
let mut left = 0;
138-
let mut right = (c as f64).sqrt() as i64;
139-
while left <= right {
140-
let num = left * left + right * right;
141-
match num.cmp(&c) {
145+
let mut a: i64 = 0;
146+
let mut b: i64 = (c as f64).sqrt() as i64;
147+
while a <= b {
148+
let s = a * a + b * b;
149+
match s.cmp(&(c as i64)) {
150+
Ordering::Equal => {
151+
return true;
152+
}
142153
Ordering::Less => {
143-
left += 1;
154+
a += 1;
144155
}
145156
Ordering::Greater => {
146-
right -= 1;
147-
}
148-
Ordering::Equal => {
149-
return true;
157+
b -= 1;
150158
}
151159
}
152160
}

solution/0600-0699/0633.Sum of Square Numbers/README_EN.md

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,11 @@
3333

3434
## Solutions
3535

36-
### Solution 1
36+
### Solution 1: Mathematics + Two Pointers
37+
38+
We can use the two-pointer method to solve this problem. Define two pointers $a$ and $b$, pointing to $0$ and $\sqrt{c}$ respectively. In each step, we calculate the value of $s = a^2 + b^2$, and then compare the size of $s$ and $c$. If $s = c$, we have found two integers $a$ and $b$ such that $a^2 + b^2 = c$. If $s < c$, we increase the value of $a$ by $1$. If $s > c$, we decrease the value of $b$ by $1$. We continue this process until we find the answer, or the value of $a$ is greater than the value of $b$, and return `false`.
39+
40+
The time complexity is $O(\sqrt{c})$, where $c$ is the given non-negative integer. The space complexity is $O(1)$.
3741

3842
<!-- tabs:start -->
3943

@@ -76,14 +80,17 @@ class Solution {
7680
class Solution {
7781
public:
7882
bool judgeSquareSum(int c) {
79-
long a = 0, b = (long) sqrt(c);
83+
long long a = 0, b = sqrt(c);
8084
while (a <= b) {
81-
long s = a * a + b * b;
82-
if (s == c) return true;
83-
if (s < c)
85+
long long s = a * a + b * b;
86+
if (s == c) {
87+
return true;
88+
}
89+
if (s < c) {
8490
++a;
85-
else
91+
} else {
8692
--b;
93+
}
8794
}
8895
return false;
8996
}
@@ -110,12 +117,13 @@ func judgeSquareSum(c int) bool {
110117

111118
```ts
112119
function judgeSquareSum(c: number): boolean {
113-
let a = 0,
114-
b = Math.floor(Math.sqrt(c));
120+
let [a, b] = [0, Math.floor(Math.sqrt(c))];
115121
while (a <= b) {
116-
let sum = a ** 2 + b ** 2;
117-
if (sum == c) return true;
118-
if (sum < c) {
122+
const s = a * a + b * b;
123+
if (s === c) {
124+
return true;
125+
}
126+
if (s < c) {
119127
++a;
120128
} else {
121129
--b;
@@ -127,22 +135,22 @@ function judgeSquareSum(c: number): boolean {
127135

128136
```rust
129137
use std::cmp::Ordering;
138+
130139
impl Solution {
131140
pub fn judge_square_sum(c: i32) -> bool {
132-
let c = c as i64;
133-
let mut left = 0;
134-
let mut right = (c as f64).sqrt() as i64;
135-
while left <= right {
136-
let num = left * left + right * right;
137-
match num.cmp(&c) {
141+
let mut a: i64 = 0;
142+
let mut b: i64 = (c as f64).sqrt() as i64;
143+
while a <= b {
144+
let s = a * a + b * b;
145+
match s.cmp(&(c as i64)) {
146+
Ordering::Equal => {
147+
return true;
148+
}
138149
Ordering::Less => {
139-
left += 1;
150+
a += 1;
140151
}
141152
Ordering::Greater => {
142-
right -= 1;
143-
}
144-
Ordering::Equal => {
145-
return true;
153+
b -= 1;
146154
}
147155
}
148156
}

solution/0600-0699/0633.Sum of Square Numbers/Solution.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
class Solution {
22
public:
33
bool judgeSquareSum(int c) {
4-
long a = 0, b = (long) sqrt(c);
4+
long long a = 0, b = sqrt(c);
55
while (a <= b) {
6-
long s = a * a + b * b;
7-
if (s == c) return true;
8-
if (s < c)
6+
long long s = a * a + b * b;
7+
if (s == c) {
8+
return true;
9+
}
10+
if (s < c) {
911
++a;
10-
else
12+
} else {
1113
--b;
14+
}
1215
}
1316
return false;
1417
}

solution/0600-0699/0633.Sum of Square Numbers/Solution.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
use std::cmp::Ordering;
2+
23
impl Solution {
34
pub fn judge_square_sum(c: i32) -> bool {
4-
let c = c as i64;
5-
let mut left = 0;
6-
let mut right = (c as f64).sqrt() as i64;
7-
while left <= right {
8-
let num = left * left + right * right;
9-
match num.cmp(&c) {
5+
let mut a: i64 = 0;
6+
let mut b: i64 = (c as f64).sqrt() as i64;
7+
while a <= b {
8+
let s = a * a + b * b;
9+
match s.cmp(&(c as i64)) {
10+
Ordering::Equal => {
11+
return true;
12+
}
1013
Ordering::Less => {
11-
left += 1;
14+
a += 1;
1215
}
1316
Ordering::Greater => {
14-
right -= 1;
15-
}
16-
Ordering::Equal => {
17-
return true;
17+
b -= 1;
1818
}
1919
}
2020
}

solution/0600-0699/0633.Sum of Square Numbers/Solution.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
function judgeSquareSum(c: number): boolean {
2-
let a = 0,
3-
b = Math.floor(Math.sqrt(c));
2+
let [a, b] = [0, Math.floor(Math.sqrt(c))];
43
while (a <= b) {
5-
let sum = a ** 2 + b ** 2;
6-
if (sum == c) return true;
7-
if (sum < c) {
4+
const s = a * a + b * b;
5+
if (s === c) {
6+
return true;
7+
}
8+
if (s < c) {
89
++a;
910
} else {
1011
--b;

solution/0600-0699/0634.Find the Derangement of An Array/README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,7 @@ $$
5656

5757
最终答案即为 $f[n]$。注意答案的取模操作。
5858

59-
我们发现,状态转移方程中只与 $f[i - 1]$ 和 $f[i - 2]$ 有关,因此我们可以使用两个变量 $a$ 和 $b$ 来分别表示 $f[i - 1]$ 和 $f[i - 2]$,从而将空间复杂度降低到 $O(1)$。
60-
61-
时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组的长度。
59+
时间复杂度 $O(n)$,其中 $n$ 为数组的长度。空间复杂度 $O(1)$。
6260

6361
<!-- tabs:start -->
6462

@@ -116,7 +114,9 @@ func findDerangement(n int) int {
116114

117115
<!-- tabs:end -->
118116

119-
### 方法二
117+
### 方法二:动态规划(空间优化)
118+
119+
我们发现,状态转移方程中只与 $f[i - 1]$ 和 $f[i - 2]$ 有关,因此我们可以使用两个变量 $a$ 和 $b$ 来分别表示 $f[i - 1]$ 和 $f[i - 2]$,从而将空间复杂度降低到 $O(1)$。
120120

121121
<!-- tabs:start -->
122122

solution/0600-0699/0634.Find the Derangement of An Array/README_EN.md

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,24 @@
3535

3636
## Solutions
3737

38-
### Solution 1
38+
### Solution 1: Dynamic Programming
39+
40+
We define $f[i]$ as the number of derangement of an array of length $i$. Initially, $f[0] = 1$, $f[1] = 0$. The answer is $f[n]$.
41+
42+
For an array of length $i$, we consider where to place the number $1$. Suppose it is placed in the $j$-th position, where there are $i-1$ choices. Then, the number $j$ has two choices:
43+
44+
- Placed in the first position, then the remaining $i - 2$ positions have $f[i - 2]$ derangements, so there are a total of $(i - 1) \times f[i - 2]$ derangements;
45+
- Not placed in the first position, which is equivalent to the derangement of an array of length $i - 1$, so there are a total of $(i - 1) \times f[i - 1]$ derangements.
46+
47+
In summary, we have the following state transition equation:
48+
49+
$$
50+
f[i] = (i - 1) \times (f[i - 1] + f[i - 2])
51+
$$
52+
53+
The final answer is $f[n]$. Note the modulo operation in the answer.
54+
55+
The time complexity is $O(n)$, where $n$ is the length of the array. The space complexity is $O(1)$.
3956

4057
<!-- tabs:start -->
4158

@@ -93,7 +110,9 @@ func findDerangement(n int) int {
93110

94111
<!-- tabs:end -->
95112

96-
### Solution 2
113+
### Solution 2: Dynamic Programming (Space Optimization)
114+
115+
We notice that the state transition equation only relates to $f[i - 1]$ and $f[i - 2]$. Therefore, we can use two variables $a$ and $b$ to represent $f[i - 1]$ and $f[i - 2]$ respectively, thereby reducing the space complexity to $O(1)$.
97116

98117
<!-- tabs:start -->
99118

solution/0600-0699/0635.Design Log Storage System/README_EN.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,11 @@ logSystem.retrieve(&quot;2016:01:01:01:01:01&quot;, &quot;2017:01:01:23:00:00&qu
5656

5757
## Solutions
5858

59-
### Solution 1
59+
### Solution 1: String Comparison
60+
61+
Store the `id` and `timestamp` of the logs as tuples in an array. Then in the `retrieve()` method, truncate the corresponding parts of `start` and `end` based on `granularity`, and traverse the array, adding the `id` that meets the conditions to the result array.
62+
63+
In terms of time complexity, the time complexity of the `put()` method is $O(1)$, and the time complexity of the `retrieve()` method is $O(n)$, where $n$ is the length of the array.
6064

6165
<!-- tabs:start -->
6266

solution/2200-2299/2208.Minimum Operations to Halve Array Sum/README_EN.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,13 @@ It can be shown that we cannot reduce the sum by at least half in less than 3 op
5353

5454
## Solutions
5555

56-
### Solution 1
56+
### Solution 1: Greedy + Priority Queue (Max Heap)
57+
58+
According to the problem description, each operation will halve a number in the array. To minimize the number of operations that reduce the array sum by at least half, each operation should halve the current maximum value in the array.
59+
60+
Therefore, we first calculate the total sum $s$ that the array needs to reduce, and then use a priority queue (max heap) to maintain all the numbers in the array. Each time we take the maximum value $t$ from the priority queue, halve it, and then put the halved number back into the priority queue, while updating $s$, until $s \le 0$. The number of operations at this time is the answer.
61+
62+
The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Where $n$ is the length of the array.
5763

5864
<!-- tabs:start -->
5965

solution/2200-2299/2209.Minimum White Tiles After Covering With Carpets/README_EN.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,20 @@ Note that the carpets are able to overlap one another.
4949

5050
## Solutions
5151

52-
### Solution 1
52+
### Solution 1: Memoization Search
53+
54+
Design a function $dfs(i, j)$ to represent the minimum number of white bricks that are not covered starting from index $i$ using $j$ carpets. The answer is $dfs(0, numCarpets)$.
55+
56+
For index $i$, we discuss different cases:
57+
58+
- If $i \ge n$, it means that all bricks have been covered, return $0$;
59+
- If $floor[i] = 0$, there is no need to use a carpet, just skip it, that is, $dfs(i, j) = dfs(i + 1, j)$;
60+
- If $j = 0$, we can directly calculate the number of remaining white bricks that have not been covered using the prefix sum array $s$, that is, $dfs(i, j) = s[n] - s[i]$;
61+
- If $floor[i] = 1$, we can choose to use a carpet to cover it, or choose not to use a carpet to cover it, and take the minimum of the two, that is, $dfs(i, j) = min(dfs(i + 1, j), dfs(i + carpetLen, j - 1))$.
62+
63+
Use memoization search.
64+
65+
The time complexity is $O(n\times m)$, and the space complexity is $O(n\times m)$. Where $n$ and $m$ are the lengths of the string $floor$ and the value of $numCarpets$ respectively.
5366

5467
<!-- tabs:start -->
5568

0 commit comments

Comments
 (0)