Skip to content

Commit c198d59

Browse files
authoredOct 20, 2023
feat: update solutions to lc problems: No.0180,0610,1164 (#1850)
* No.0180.Consecutive Numbers * No.0610.Triangle Judgement * No.1164.Product Price at a Given Date
1 parent 28f3092 commit c198d59

File tree

9 files changed

+153
-92
lines changed

9 files changed

+153
-92
lines changed
 

‎.prettierrc

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"overrides": [
1515
{
1616
"files": [
17+
"solution/0100-0199/0180.Consecutive Numbers/Solution.sql",
1718
"solution/0500-0599/0550.Game Play Analysis IV/Solution.sql",
1819
"solution/0500-0599/0578.Get Highest Answer Rate Question/Solution.sql",
1920
"solution/0600-0699/0610.Triangle Judgement/Solution.sql",
@@ -55,4 +56,4 @@
5556
}
5657
}
5758
]
58-
}
59+
}

‎solution/0100-0199/0180.Consecutive Numbers/README.md

+44-8
Original file line numberDiff line numberDiff line change
@@ -57,26 +57,62 @@ Result 表:
5757

5858
<!-- 这里可写通用的实现逻辑 -->
5959

60+
**方法一:两次连接**
61+
62+
我们可以使用两次连接来解决这个问题。
63+
64+
我们首先进行一次自连接,连接条件是 `l1.num = l2.num` 并且 `l1.id = l2.id - 1`,这样我们就可以找出所有至少连续出现两次的数字。然后,我们再进行一次自连接,连接条件是 `l2.num = l3.num` 并且 `l2.id = l3.id - 1`,这样我们就可以找出所有至少连续出现三次的数字。最后,我们只需要筛选出去重的 `l2.num` 即可。
65+
66+
**方法二:窗口函数**
67+
68+
我们可以使用窗口函数 `LAG``LEAD` 来获取上一行的 `num` 和下一行的 `num`,记录在字段 $a$ 和 $b$ 中。最后,我们只需要筛选出 $a =num$ 并且 $b = num$ 的行,这些行就是至少连续出现三次的数字。注意,我们需要使用 `DISTINCT` 关键字来对结果去重。
69+
70+
我们也可以对数字进行分组,具体做法是使用 `IF` 函数来判断当前行与前一行的 `num` 是否相等,如果相等则记为 $0$,否则记为 $1$,然后使用窗口函数 `SUM` 来计算前缀和,这样计算出的前缀和就是分组的标识。最后,我们只需要按照分组标识进行分组,然后筛选出每组中的行数大于等于 $3$ 的数字即可。同样,我们需要使用 `DISTINCT` 关键字来对结果去重。
71+
6072
<!-- tabs:start -->
6173

6274
### **SQL**
6375

76+
```sql
77+
# Write your MySQL query statement below
78+
SELECT DISTINCT l2.num AS ConsecutiveNums
79+
FROM
80+
Logs AS l1
81+
JOIN Logs AS l2 ON l1.id = l2.id - 1 AND l1.num = l2.num
82+
JOIN Logs AS l3 ON l2.id = l3.id - 1 AND l2.num = l3.num;
83+
```
84+
85+
```sql
86+
# Write your MySQL query statement below
87+
WITH
88+
T AS (
89+
SELECT
90+
*,
91+
LAG(num) OVER () AS a,
92+
LEAD(num) OVER () AS b
93+
FROM Logs
94+
)
95+
SELECT DISTINCT num AS ConsecutiveNums
96+
FROM T
97+
WHERE a = num AND b = num;
98+
```
99+
64100
```sql
65101
# Write your MySQL query statement below
66102
WITH
67-
t AS (
103+
T AS (
68104
SELECT
69105
*,
70-
CASE
71-
WHEN (LAG(num) OVER (ORDER BY id)) = num THEN 0
72-
ELSE 1
73-
END AS mark
106+
IF(num = (LAG(num) OVER ()), 0, 1) AS st
74107
FROM Logs
75108
),
76-
p AS (SELECT num, SUM(mark) OVER (ORDER BY id) AS gid FROM t)
109+
S AS (
110+
SELECT *, SUM(st) OVER (ORDER BY id) AS p
111+
FROM T
112+
)
77113
SELECT DISTINCT num AS ConsecutiveNums
78-
FROM p
79-
GROUP BY gid
114+
FROM S
115+
GROUP BY p
80116
HAVING COUNT(1) >= 3;
81117
```
82118

‎solution/0100-0199/0180.Consecutive Numbers/README_EN.md

+44-8
Original file line numberDiff line numberDiff line change
@@ -53,26 +53,62 @@ Logs table:
5353

5454
## Solutions
5555

56+
**Solution 1: Two Joins**
57+
58+
We can use two joins to solve this problem.
59+
60+
First, we perform a self-join with the condition `l1.num = l2.num` and `l1.id = l2.id - 1`, so that we can find all numbers that appear at least twice in a row. Then, we perform another self-join with the condition `l2.num = l3.num` and `l2.id = l3.id - 1`, so that we can find all numbers that appear at least three times in a row. Finally, we only need to select the distinct `l2.num`.
61+
62+
**Solution 2: Window Function**
63+
64+
We can use the window functions `LAG` and `LEAD` to obtain the `num` of the previous row and the next row of the current row, and record them in the fields $a$ and $b$, respectively. Finally, we only need to filter out the rows where $a = num$ and $b = num$, which are the numbers that appear at least three times in a row. Note that we need to use the `DISTINCT` keyword to remove duplicates from the results.
65+
66+
We can also group the numbers by using the `IF` function to determine whether the `num` of the current row is equal to the `num` of the previous row. If they are equal, we set it to $0$, otherwise we set it to $1$. Then, we use the window function `SUM` to calculate the prefix sum, which is the grouping identifier. Finally, we only need to group by the grouping identifier and filter out the numbers with a row count greater than or equal to $3$ in each group. Similarly, we need to use the `DISTINCT` keyword to remove duplicates from the results.
67+
5668
<!-- tabs:start -->
5769

5870
### **SQL**
5971

72+
```sql
73+
# Write your MySQL query statement below
74+
SELECT DISTINCT l2.num AS ConsecutiveNums
75+
FROM
76+
Logs AS l1
77+
JOIN Logs AS l2 ON l1.id = l2.id - 1 AND l1.num = l2.num
78+
JOIN Logs AS l3 ON l2.id = l3.id - 1 AND l2.num = l3.num;
79+
```
80+
81+
```sql
82+
# Write your MySQL query statement below
83+
WITH
84+
T AS (
85+
SELECT
86+
*,
87+
LAG(num) OVER () AS a,
88+
LEAD(num) OVER () AS b
89+
FROM Logs
90+
)
91+
SELECT DISTINCT num AS ConsecutiveNums
92+
FROM T
93+
WHERE a = num AND b = num;
94+
```
95+
6096
```sql
6197
# Write your MySQL query statement below
6298
WITH
63-
t AS (
99+
T AS (
64100
SELECT
65101
*,
66-
CASE
67-
WHEN (LAG(num) OVER (ORDER BY id)) = num THEN 0
68-
ELSE 1
69-
END AS mark
102+
IF(num = (LAG(num) OVER ()), 0, 1) AS st
70103
FROM Logs
71104
),
72-
p AS (SELECT num, SUM(mark) OVER (ORDER BY id) AS gid FROM t)
105+
S AS (
106+
SELECT *, SUM(st) OVER (ORDER BY id) AS p
107+
FROM T
108+
)
73109
SELECT DISTINCT num AS ConsecutiveNums
74-
FROM p
75-
GROUP BY gid
110+
FROM S
111+
GROUP BY p
76112
HAVING COUNT(1) >= 3;
77113
```
78114

Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
# Write your MySQL query statement below
22
WITH
3-
t AS (
3+
T AS (
44
SELECT
55
*,
6-
CASE
7-
WHEN (LAG(num) OVER (ORDER BY id)) = num THEN 0
8-
ELSE 1
9-
END AS mark
6+
IF(num = (LAG(num) OVER ()), 0, 1) AS st
107
FROM Logs
118
),
12-
p AS (SELECT num, SUM(mark) OVER (ORDER BY id) AS gid FROM t)
9+
S AS (
10+
SELECT *, SUM(st) OVER (ORDER BY id) AS p
11+
FROM T
12+
)
1313
SELECT DISTINCT num AS ConsecutiveNums
14-
FROM p
15-
GROUP BY gid
14+
FROM S
15+
GROUP BY p
1616
HAVING COUNT(1) >= 3;

‎solution/0600-0699/0610.Triangle Judgement/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ Triangle 表:
5353

5454
<!-- 这里可写通用的实现逻辑 -->
5555

56-
**方法一:if 语句 + 三角形判断条件**
56+
**方法一:IF 语句 + 三角形判断条件**
5757

58-
三条边能否构成三角形的条件是:任意两边之和大于第三边。因此,我们可以使用 `if` 语句来判断是否满足这个条件,如果满足则返回 `Yes`,否则返回 `No`
58+
三条边能否构成三角形的条件是:任意两边之和大于第三边。因此,我们可以使用 `IF` 语句来判断是否满足这个条件,如果满足则返回 `Yes`,否则返回 `No`
5959

6060
<!-- tabs:start -->
6161

‎solution/0600-0699/0610.Triangle Judgement/README_EN.md

+4
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ Triangle table:
4949

5050
## Solutions
5151

52+
**Solution 1: IF Statement + Triangle Inequality**
53+
54+
The condition for whether three sides can form a triangle is that the sum of any two sides is greater than the third side. Therefore, we can use an `IF` statement to determine whether this condition is satisfied. If it is satisfied, we return `Yes`, otherwise we return `No`.
55+
5256
<!-- tabs:start -->
5357

5458
### **SQL**

‎solution/1100-1199/1164.Product Price at a Given Date/README.md

+18-23
Original file line numberDiff line numberDiff line change
@@ -57,38 +57,33 @@ Products 表:
5757

5858
<!-- 这里可写通用的实现逻辑 -->
5959

60+
**方法一:子查询 + 连接**
61+
62+
我们可以使用子查询,找出每个产品在给定日期之前最后一次价格变更的价格,记录在 `P` 表中。然后,我们再找出所有产品的 `product_id`,记录在 `T` 表中。最后,我们将 `T` 表和 `P` 表按照 `product_id` 进行左连接,即可得到最终结果。
63+
6064
<!-- tabs:start -->
6165

6266
### **SQL**
6367

6468
```sql
6569
# Write your MySQL query statement below
66-
SELECT
67-
p1.product_id AS product_id,
68-
IFNULL(p2.price, 10) AS price
69-
FROM
70-
(
71-
SELECT DISTINCT
72-
(product_id) AS product_id
70+
WITH
71+
T AS (SELECT DISTINCT product_id FROM Products),
72+
P AS (
73+
SELECT product_id, new_price AS price
7374
FROM Products
74-
) AS p1
75-
LEFT JOIN (
76-
SELECT
77-
t1.product_id,
78-
t1.new_price AS price
79-
FROM
80-
Products AS t1
81-
JOIN (
82-
SELECT
83-
product_id,
84-
MAX(change_date) AS change_date
75+
WHERE
76+
(product_id, change_date) IN (
77+
SELECT product_id, MAX(change_date) AS change_date
8578
FROM Products
8679
WHERE change_date <= '2019-08-16'
87-
GROUP BY product_id
88-
) AS t2
89-
ON t1.product_id = t2.product_id AND t1.change_date = t2.change_date
90-
) AS p2
91-
ON p1.product_id = p2.product_id;
80+
GROUP BY 1
81+
)
82+
)
83+
SELECT product_id, IFNULL(price, 10) AS price
84+
FROM
85+
T
86+
LEFT JOIN P USING (product_id);
9287
```
9388

9489
```sql

‎solution/1100-1199/1164.Product Price at a Given Date/README_EN.md

+18-23
Original file line numberDiff line numberDiff line change
@@ -53,38 +53,33 @@ Products table:
5353

5454
## Solutions
5555

56+
**Solution 1: Subquery + Join**
57+
58+
We can use a subquery to find the price of the last price change for each product before the given date, and record it in the `P` table. Then, we can find all `product_id`s in the `T` table. Finally, we can left join the `T` table with the `P` table on `product_id` to get the final result.
59+
5660
<!-- tabs:start -->
5761

5862
### **SQL**
5963

6064
```sql
6165
# Write your MySQL query statement below
62-
SELECT
63-
p1.product_id AS product_id,
64-
IFNULL(p2.price, 10) AS price
65-
FROM
66-
(
67-
SELECT DISTINCT
68-
(product_id) AS product_id
66+
WITH
67+
T AS (SELECT DISTINCT product_id FROM Products),
68+
P AS (
69+
SELECT product_id, new_price AS price
6970
FROM Products
70-
) AS p1
71-
LEFT JOIN (
72-
SELECT
73-
t1.product_id,
74-
t1.new_price AS price
75-
FROM
76-
Products AS t1
77-
JOIN (
78-
SELECT
79-
product_id,
80-
MAX(change_date) AS change_date
71+
WHERE
72+
(product_id, change_date) IN (
73+
SELECT product_id, MAX(change_date) AS change_date
8174
FROM Products
8275
WHERE change_date <= '2019-08-16'
83-
GROUP BY product_id
84-
) AS t2
85-
ON t1.product_id = t2.product_id AND t1.change_date = t2.change_date
86-
) AS p2
87-
ON p1.product_id = p2.product_id;
76+
GROUP BY 1
77+
)
78+
)
79+
SELECT product_id, IFNULL(price, 10) AS price
80+
FROM
81+
T
82+
LEFT JOIN P USING (product_id);
8883
```
8984

9085
```sql
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,18 @@
11
# Write your MySQL query statement below
22
WITH
3+
T AS (SELECT DISTINCT product_id FROM Products),
34
P AS (
4-
SELECT p1.product_id, new_price, change_date
5-
FROM
6-
(
7-
SELECT DISTINCT product_id
5+
SELECT product_id, new_price AS price
6+
FROM Products
7+
WHERE
8+
(product_id, change_date) IN (
9+
SELECT product_id, MAX(change_date) AS change_date
810
FROM Products
9-
) AS p1
10-
LEFT JOIN Products AS p2
11-
ON p1.product_id = p2.product_id AND p2.change_date <= '2019-08-16'
12-
),
13-
T AS (
14-
SELECT
15-
*,
16-
RANK() OVER (
17-
PARTITION BY product_id
18-
ORDER BY change_date DESC
19-
) AS rk
20-
FROM P
11+
WHERE change_date <= '2019-08-16'
12+
GROUP BY 1
13+
)
2114
)
22-
SELECT product_id, IFNULL(new_price, 10) AS price
23-
FROM T
24-
WHERE rk = 1;
15+
SELECT product_id, IFNULL(price, 10) AS price
16+
FROM
17+
T
18+
LEFT JOIN P USING (product_id);

0 commit comments

Comments
 (0)
Please sign in to comment.