Skip to content

Commit 044942b

Browse files
authored
feat: add solutions to lc problems: No.3642,3643 (#4635)
* No.3642.Find Books with Polarized Opinions * No.3643.Flip Square Submatrix Vertically
1 parent ac74122 commit 044942b

File tree

11 files changed

+416
-10
lines changed

11 files changed

+416
-10
lines changed

solution/3600-3699/3642.Find Books with Polarized Opinions/README.md

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,14 +167,94 @@ Each row represents a reading session where someone read a portion of a book. se
167167

168168
<!-- solution:start -->
169169

170-
### 方法一
170+
### 方法一:连接 + 分组聚合
171+
172+
我们可以通过连接 `books` 表和 `reading_sessions` 表,然后对结果进行分组和聚合来实现。
173+
174+
首先,我们需要计算每本书的评分范围、极端评分的数量和极端评分的比例。
175+
176+
然后,我们可以根据这些指标筛选出符合条件的书籍。
177+
178+
最后,按照极端评分比例和书名的降序排列结果。
171179

172180
<!-- tabs:start -->
173181

174182
#### MySQL
175183

176184
```sql
185+
# Write your MySQL query statement below
186+
SELECT
187+
book_id,
188+
title,
189+
author,
190+
genre,
191+
pages,
192+
(MAX(session_rating) - MIN(session_rating)) AS rating_spread,
193+
ROUND((SUM(session_rating <= 2) + SUM(session_rating >= 4)) / COUNT(1), 2) polarization_score
194+
FROM
195+
books
196+
JOIN reading_sessions USING (book_id)
197+
GROUP BY book_id
198+
HAVING
199+
COUNT(1) >= 5
200+
AND MAX(session_rating) >= 4
201+
AND MIN(session_rating) <= 2
202+
AND polarization_score >= 0.6
203+
ORDER BY polarization_score DESC, title DESC;
204+
```
177205

206+
#### Pandas
207+
208+
```python
209+
import pandas as pd
210+
from decimal import Decimal, ROUND_HALF_UP
211+
212+
213+
def find_polarized_books(
214+
books: pd.DataFrame, reading_sessions: pd.DataFrame
215+
) -> pd.DataFrame:
216+
df = books.merge(reading_sessions, on="book_id")
217+
agg_df = (
218+
df.groupby(["book_id", "title", "author", "genre", "pages"])
219+
.agg(
220+
max_rating=("session_rating", "max"),
221+
min_rating=("session_rating", "min"),
222+
rating_spread=("session_rating", lambda x: x.max() - x.min()),
223+
count_sessions=("session_rating", "count"),
224+
low_or_high_count=("session_rating", lambda x: ((x <= 2) | (x >= 4)).sum()),
225+
)
226+
.reset_index()
227+
)
228+
229+
agg_df["polarization_score"] = agg_df.apply(
230+
lambda r: float(
231+
Decimal(r["low_or_high_count"] / r["count_sessions"]).quantize(
232+
Decimal("0.01"), rounding=ROUND_HALF_UP
233+
)
234+
),
235+
axis=1,
236+
)
237+
238+
result = agg_df[
239+
(agg_df["count_sessions"] >= 5)
240+
& (agg_df["max_rating"] >= 4)
241+
& (agg_df["min_rating"] <= 2)
242+
& (agg_df["polarization_score"] >= 0.6)
243+
]
244+
245+
return result.sort_values(
246+
by=["polarization_score", "title"], ascending=[False, False]
247+
)[
248+
[
249+
"book_id",
250+
"title",
251+
"author",
252+
"genre",
253+
"pages",
254+
"rating_spread",
255+
"polarization_score",
256+
]
257+
]
178258
```
179259

180260
<!-- tabs:end -->

solution/3600-3699/3642.Find Books with Polarized Opinions/README_EN.md

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,14 +167,94 @@ Each row represents a reading session where someone read a portion of a book. se
167167

168168
<!-- solution:start -->
169169

170-
### Solution 1
170+
### Solution 1: Join + Group Aggregation
171+
172+
We can implement this by joining the `books` table with the `reading_sessions` table, then grouping and aggregating the results.
173+
174+
First, we need to calculate the rating range, the number of extreme ratings, and the proportion of extreme ratings for each book.
175+
176+
Then, we can filter out books that meet the criteria based on these metrics.
177+
178+
Finally, sort the results by extreme rating proportion and book title in descending order.
171179

172180
<!-- tabs:start -->
173181

174182
#### MySQL
175183

176184
```sql
185+
# Write your MySQL query statement below
186+
SELECT
187+
book_id,
188+
title,
189+
author,
190+
genre,
191+
pages,
192+
(MAX(session_rating) - MIN(session_rating)) AS rating_spread,
193+
ROUND((SUM(session_rating <= 2) + SUM(session_rating >= 4)) / COUNT(1), 2) polarization_score
194+
FROM
195+
books
196+
JOIN reading_sessions USING (book_id)
197+
GROUP BY book_id
198+
HAVING
199+
COUNT(1) >= 5
200+
AND MAX(session_rating) >= 4
201+
AND MIN(session_rating) <= 2
202+
AND polarization_score >= 0.6
203+
ORDER BY polarization_score DESC, title DESC;
204+
```
177205

206+
#### Pandas
207+
208+
```python
209+
import pandas as pd
210+
from decimal import Decimal, ROUND_HALF_UP
211+
212+
213+
def find_polarized_books(
214+
books: pd.DataFrame, reading_sessions: pd.DataFrame
215+
) -> pd.DataFrame:
216+
df = books.merge(reading_sessions, on="book_id")
217+
agg_df = (
218+
df.groupby(["book_id", "title", "author", "genre", "pages"])
219+
.agg(
220+
max_rating=("session_rating", "max"),
221+
min_rating=("session_rating", "min"),
222+
rating_spread=("session_rating", lambda x: x.max() - x.min()),
223+
count_sessions=("session_rating", "count"),
224+
low_or_high_count=("session_rating", lambda x: ((x <= 2) | (x >= 4)).sum()),
225+
)
226+
.reset_index()
227+
)
228+
229+
agg_df["polarization_score"] = agg_df.apply(
230+
lambda r: float(
231+
Decimal(r["low_or_high_count"] / r["count_sessions"]).quantize(
232+
Decimal("0.01"), rounding=ROUND_HALF_UP
233+
)
234+
),
235+
axis=1,
236+
)
237+
238+
result = agg_df[
239+
(agg_df["count_sessions"] >= 5)
240+
& (agg_df["max_rating"] >= 4)
241+
& (agg_df["min_rating"] <= 2)
242+
& (agg_df["polarization_score"] >= 0.6)
243+
]
244+
245+
return result.sort_values(
246+
by=["polarization_score", "title"], ascending=[False, False]
247+
)[
248+
[
249+
"book_id",
250+
"title",
251+
"author",
252+
"genre",
253+
"pages",
254+
"rating_spread",
255+
"polarization_score",
256+
]
257+
]
178258
```
179259

180260
<!-- tabs:end -->
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import pandas as pd
2+
from decimal import Decimal, ROUND_HALF_UP
3+
4+
5+
def find_polarized_books(
6+
books: pd.DataFrame, reading_sessions: pd.DataFrame
7+
) -> pd.DataFrame:
8+
df = books.merge(reading_sessions, on="book_id")
9+
agg_df = (
10+
df.groupby(["book_id", "title", "author", "genre", "pages"])
11+
.agg(
12+
max_rating=("session_rating", "max"),
13+
min_rating=("session_rating", "min"),
14+
rating_spread=("session_rating", lambda x: x.max() - x.min()),
15+
count_sessions=("session_rating", "count"),
16+
low_or_high_count=("session_rating", lambda x: ((x <= 2) | (x >= 4)).sum()),
17+
)
18+
.reset_index()
19+
)
20+
21+
agg_df["polarization_score"] = agg_df.apply(
22+
lambda r: float(
23+
Decimal(r["low_or_high_count"] / r["count_sessions"]).quantize(
24+
Decimal("0.01"), rounding=ROUND_HALF_UP
25+
)
26+
),
27+
axis=1,
28+
)
29+
30+
result = agg_df[
31+
(agg_df["count_sessions"] >= 5)
32+
& (agg_df["max_rating"] >= 4)
33+
& (agg_df["min_rating"] <= 2)
34+
& (agg_df["polarization_score"] >= 0.6)
35+
]
36+
37+
return result.sort_values(
38+
by=["polarization_score", "title"], ascending=[False, False]
39+
)[
40+
[
41+
"book_id",
42+
"title",
43+
"author",
44+
"genre",
45+
"pages",
46+
"rating_spread",
47+
"polarization_score",
48+
]
49+
]
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Write your MySQL query statement below
2+
SELECT
3+
book_id,
4+
title,
5+
author,
6+
genre,
7+
pages,
8+
(MAX(session_rating) - MIN(session_rating)) AS rating_spread,
9+
ROUND((SUM(session_rating <= 2) + SUM(session_rating >= 4)) / COUNT(1), 2) polarization_score
10+
FROM
11+
books
12+
JOIN reading_sessions USING (book_id)
13+
GROUP BY book_id
14+
HAVING
15+
COUNT(1) >= 5
16+
AND MAX(session_rating) >= 4
17+
AND MIN(session_rating) <= 2
18+
AND polarization_score >= 0.6
19+
ORDER BY polarization_score DESC, title DESC;

solution/3600-3699/3643.Flip Square Submatrix Vertically/README.md

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,32 +68,95 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3643.Fl
6868

6969
<!-- solution:start -->
7070

71-
### 方法一
71+
### 方法一:模拟
72+
73+
我们从第 $x$ 行开始,一共翻转 $\lfloor \frac{k}{2} \rfloor$ 行。
74+
75+
对于每一行 $i$,我们需要将其与对应的行 $i_2$ 进行交换,其中 $i_2 = x + k - 1 - (i - x)$。
76+
77+
在交换时,我们需要遍历 $j \in [y, y + k)$,将 $\text{grid}[i][j]$ 和 $\text{grid}[i_2][j]$ 进行交换。
78+
79+
最后,返回更新后的矩阵。
80+
81+
时间复杂度 $O(k^2)$,其中 $k$ 是子矩阵的边长。空间复杂度 $O(1)$。
7282

7383
<!-- tabs:start -->
7484

7585
#### Python3
7686

7787
```python
78-
88+
class Solution:
89+
def reverseSubmatrix(
90+
self, grid: List[List[int]], x: int, y: int, k: int
91+
) -> List[List[int]]:
92+
for i in range(x, x + k // 2):
93+
i2 = x + k - 1 - (i - x)
94+
for j in range(y, y + k):
95+
grid[i][j], grid[i2][j] = grid[i2][j], grid[i][j]
96+
return grid
7997
```
8098

8199
#### Java
82100

83101
```java
84-
102+
class Solution {
103+
public int[][] reverseSubmatrix(int[][] grid, int x, int y, int k) {
104+
for (int i = x; i < x + k / 2; i++) {
105+
int i2 = x + k - 1 - (i - x);
106+
for (int j = y; j < y + k; j++) {
107+
int t = grid[i][j];
108+
grid[i][j] = grid[i2][j];
109+
grid[i2][j] = t;
110+
}
111+
}
112+
return grid;
113+
}
114+
}
85115
```
86116

87117
#### C++
88118

89119
```cpp
90-
120+
class Solution {
121+
public:
122+
vector<vector<int>> reverseSubmatrix(vector<vector<int>>& grid, int x, int y, int k) {
123+
for (int i = x; i < x + k / 2; i++) {
124+
int i2 = x + k - 1 - (i - x);
125+
for (int j = y; j < y + k; j++) {
126+
swap(grid[i][j], grid[i2][j]);
127+
}
128+
}
129+
return grid;
130+
}
131+
};
91132
```
92133
93134
#### Go
94135
95136
```go
137+
func reverseSubmatrix(grid [][]int, x int, y int, k int) [][]int {
138+
for i := x; i < x+k/2; i++ {
139+
i2 := x + k - 1 - (i - x)
140+
for j := y; j < y+k; j++ {
141+
grid[i][j], grid[i2][j] = grid[i2][j], grid[i][j]
142+
}
143+
}
144+
return grid
145+
}
146+
```
96147

148+
#### TypeScript
149+
150+
```ts
151+
function reverseSubmatrix(grid: number[][], x: number, y: number, k: number): number[][] {
152+
for (let i = x; i < x + Math.floor(k / 2); i++) {
153+
const i2 = x + k - 1 - (i - x);
154+
for (let j = y; j < y + k; j++) {
155+
[grid[i][j], grid[i2][j]] = [grid[i2][j], grid[i][j]];
156+
}
157+
}
158+
return grid;
159+
}
97160
```
98161

99162
<!-- tabs:end -->

0 commit comments

Comments
 (0)