Skip to content

Commit 6a9164e

Browse files
authored
feat: update solutions to lc problems: No.1454,1455 (doocs#3356)
1 parent a85653a commit 6a9164e

File tree

7 files changed

+106
-55
lines changed

7 files changed

+106
-55
lines changed

.prettierignore

+1-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ node_modules/
1616
/solution/0100-0199/0177.Nth Highest Salary/Solution.sql
1717
/solution/0100-0199/0178.Rank Scores/Solution2.sql
1818
/solution/0500-0599/0586.Customer Placing the Largest Number of Orders/Solution2.sql
19-
/solution/1400-1499/1454.Active Users/Solution.sql
2019
/solution/1600-1699/1635.Hopper Company Queries I/Solution.sql
2120
/solution/2100-2199/2118.Build the Equation/Solution.sql
2221
/solution/2100-2199/2175.The Change in Global Rankings/Solution.sql
@@ -25,4 +24,4 @@ node_modules/
2524
/solution/2200-2299/2252.Dynamic Pivoting of a Table/Solution.sql
2625
/solution/2200-2299/2253.Dynamic Unpivoting of a Table/Solution.sql
2726
/solution/3100-3199/3150.Invalid Tweets II/Solution.sql
28-
/solution/3100-3199/3198.Find Cities in Each State/Solution.sql
27+
/solution/3100-3199/3198.Find Cities in Each State/Solution.sql

solution/1400-1499/1454.Active Users/README.md

+31-13
Original file line numberDiff line numberDiff line change
@@ -104,26 +104,44 @@ id = 7 的用户 Jonathon 在不同的 6 天内登录了 7 次, , 6 天中有 5
104104

105105
<!-- solution:start -->
106106

107-
### 方法一
107+
### 方法一: 使用窗口函数
108+
109+
我们先将 `Logins` 表和 `Accounts` 表连接起来,并且去重,得到临时表 `T`
110+
111+
然后我们使用窗口函数 `ROW_NUMBER()`,计算出每个用户 `id` 的登录日期的基准日期 `g`,如果用户连续登录 5 天,那么他们的 `g` 值是相同的。
112+
113+
最后,我们按照 `id``g` 进行分组,统计每个用户的登录次数,如果登录次数大于等于 5,那么这个用户就是活跃用户。
108114

109115
<!-- tabs:start -->
110116

111117
#### MySQL
112118

113119
```sql
114120
# Write your MySQL query statement below
115-
WITH t AS
116-
(SELECT *,
117-
SUM(id) over(partition by id
118-
ORDER BY login_date range interval 4 day preceding)/id cnt
119-
FROM
120-
(SELECT DISTINCT *
121-
FROM Accounts
122-
JOIN Logins using(id) ) tt )
123-
SELECT DISTINCT id,
124-
name
125-
FROM t
126-
WHERE cnt=5;
121+
WITH
122+
T AS (
123+
SELECT DISTINCT *
124+
FROM
125+
Logins
126+
JOIN Accounts USING (id)
127+
),
128+
P AS (
129+
SELECT
130+
*,
131+
DATE_SUB(
132+
login_date,
133+
INTERVAL ROW_NUMBER() OVER (
134+
PARTITION BY id
135+
ORDER BY login_date
136+
) DAY
137+
) g
138+
FROM T
139+
)
140+
SELECT DISTINCT id, name
141+
FROM P
142+
GROUP BY id, g
143+
HAVING COUNT(*) >= 5
144+
ORDER BY 1;
127145
```
128146

129147
<!-- tabs:end -->

solution/1400-1499/1454.Active Users/README_EN.md

+34-16
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ This table contains the account id of the user who logged in and the login date.
5858
<p><strong class="example">Example 1:</strong></p>
5959

6060
<pre>
61-
<strong>Input:</strong>
61+
<strong>Input:</strong>
6262
Accounts table:
6363
+----+----------+
6464
| id | name |
@@ -80,13 +80,13 @@ Logins table:
8080
| 1 | 2020-06-07 |
8181
| 7 | 2020-06-10 |
8282
+----+------------+
83-
<strong>Output:</strong>
83+
<strong>Output:</strong>
8484
+----+----------+
8585
| id | name |
8686
+----+----------+
8787
| 7 | Jonathan |
8888
+----+----------+
89-
<strong>Explanation:</strong>
89+
<strong>Explanation:</strong>
9090
User Winston with id = 1 logged in 2 times only in 2 different days, so, Winston is not an active user.
9191
User Jonathan with id = 7 logged in 7 times in 6 different days, five of them were consecutive days, so, Jonathan is an active user.
9292
</pre>
@@ -100,26 +100,44 @@ User Jonathan with id = 7 logged in 7 times in 6 different days, five of them we
100100

101101
<!-- solution:start -->
102102

103-
### Solution 1
103+
### Solution 1: Using Window Functions
104+
105+
First, we join the `Logins` table and the `Accounts` table, and remove duplicates to get the temporary table `T`.
106+
107+
Then, we use the window function `ROW_NUMBER()` to calculate the base login date `g` for each user `id`. If a user logs in for 5 consecutive days, their `g` values are the same.
108+
109+
Finally, we group by `id` and `g` to count the number of logins for each user. If the number of logins is greater than or equal to 5, then the user is considered active.
104110

105111
<!-- tabs:start -->
106112

107113
#### MySQL
108114

109115
```sql
110116
# Write your MySQL query statement below
111-
WITH t AS
112-
(SELECT *,
113-
SUM(id) over(partition by id
114-
ORDER BY login_date range interval 4 day preceding)/id cnt
115-
FROM
116-
(SELECT DISTINCT *
117-
FROM Accounts
118-
JOIN Logins using(id) ) tt )
119-
SELECT DISTINCT id,
120-
name
121-
FROM t
122-
WHERE cnt=5;
117+
WITH
118+
T AS (
119+
SELECT DISTINCT *
120+
FROM
121+
Logins
122+
JOIN Accounts USING (id)
123+
),
124+
P AS (
125+
SELECT
126+
*,
127+
DATE_SUB(
128+
login_date,
129+
INTERVAL ROW_NUMBER() OVER (
130+
PARTITION BY id
131+
ORDER BY login_date
132+
) DAY
133+
) g
134+
FROM T
135+
)
136+
SELECT DISTINCT id, name
137+
FROM P
138+
GROUP BY id, g
139+
HAVING COUNT(*) >= 5
140+
ORDER BY 1;
123141
```
124142

125143
<!-- tabs:end -->
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
11
# Write your MySQL query statement below
2-
WITH t AS
3-
(SELECT *,
4-
SUM(id) over(partition by id
5-
ORDER BY login_date range interval 4 day preceding)/id cnt
6-
FROM
7-
(SELECT DISTINCT *
8-
FROM Accounts
9-
JOIN Logins using(id) ) tt )
10-
SELECT DISTINCT id,
11-
name
12-
FROM t
13-
WHERE cnt=5;
2+
WITH
3+
T AS (
4+
SELECT DISTINCT *
5+
FROM
6+
Logins
7+
JOIN Accounts USING (id)
8+
),
9+
P AS (
10+
SELECT
11+
*,
12+
DATE_SUB(
13+
login_date,
14+
INTERVAL ROW_NUMBER() OVER (
15+
PARTITION BY id
16+
ORDER BY login_date
17+
) DAY
18+
) g
19+
FROM T
20+
)
21+
SELECT DISTINCT id, name
22+
FROM P
23+
GROUP BY id, g
24+
HAVING COUNT(*) >= 5
25+
ORDER BY 1;

solution/1400-1499/1455.Check If a Word Occurs As a Prefix of Any Word in a Sentence/README.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,9 @@ tags:
7171

7272
### 方法一:字符串分割
7373

74-
将 $sentence$ 按空格分割为 $words$,然后遍历 $words$,检查 $words[i]$ 是否是 $searchWord$ 的前缀,是则返回 $i+1$。若遍历结束,所有单词都不满足,返回 $-1$。
74+
我们将 $\textit{sentence}$ 按空格分割为 $\textit{words}$,然后遍历 $\textit{words}$,检查 $\textit{words}[i]$ 是否是 $\textit{searchWord}$ 的前缀,是则返回 $i+1$。若遍历结束,所有单词都不满足,返回 $-1$。
7575

76-
时间复杂度 $O(mn)$。其中 $m$ 是 $sentence$ 的长度,而 $n$ 是 $searchWord$ 的长度。
76+
时间复杂度 $O(m \times n)$,空间复杂度 $O(m)$。其中 $m$ 和 $n$ 分别是 $\textit{sentence}$ 和 $\textit{searchWord}$ 的长度。
7777

7878
<!-- tabs:start -->
7979

@@ -176,9 +176,9 @@ class Solution {
176176
* @return Integer
177177
*/
178178
function isPrefixOfWord($sentence, $searchWord) {
179-
$arr = explode(' ', $sentence);
180-
for ($i = 0; $i < count($arr); $i++) {
181-
if (strpos($arr[$i], $searchWord) === 0) {
179+
$words = explode(' ', $sentence);
180+
for ($i = 0; $i < count($words); ++$i) {
181+
if (strpos($words[$i], $searchWord) === 0) {
182182
return $i + 1;
183183
}
184184
}

solution/1400-1499/1455.Check If a Word Occurs As a Prefix of Any Word in a Sentence/README_EN.md

+8-4
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,11 @@ tags:
6767

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

70-
### Solution 1
70+
### Solution 1: String Splitting
71+
72+
We split $\textit{sentence}$ by spaces into $\textit{words}$, then iterate through $\textit{words}$ to check if $\textit{words}[i]$ is a prefix of $\textit{searchWord}$. If it is, we return $i+1$. If the iteration completes and no words satisfy the condition, we return $-1$.
73+
74+
The time complexity is $O(m \times n)$, and the space complexity is $O(m)$. Here, $m$ and $n$ are the lengths of $\textit{sentence}$ and $\textit{searchWord}$, respectively.
7175

7276
<!-- tabs:start -->
7377

@@ -170,9 +174,9 @@ class Solution {
170174
* @return Integer
171175
*/
172176
function isPrefixOfWord($sentence, $searchWord) {
173-
$arr = explode(' ', $sentence);
174-
for ($i = 0; $i < count($arr); $i++) {
175-
if (strpos($arr[$i], $searchWord) === 0) {
177+
$words = explode(' ', $sentence);
178+
for ($i = 0; $i < count($words); ++$i) {
179+
if (strpos($words[$i], $searchWord) === 0) {
176180
return $i + 1;
177181
}
178182
}

solution/1400-1499/1455.Check If a Word Occurs As a Prefix of Any Word in a Sentence/Solution.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ class Solution {
55
* @return Integer
66
*/
77
function isPrefixOfWord($sentence, $searchWord) {
8-
$arr = explode(' ', $sentence);
9-
for ($i = 0; $i < count($arr); $i++) {
10-
if (strpos($arr[$i], $searchWord) === 0) {
8+
$words = explode(' ', $sentence);
9+
for ($i = 0; $i < count($words); ++$i) {
10+
if (strpos($words[$i], $searchWord) === 0) {
1111
return $i + 1;
1212
}
1313
}

0 commit comments

Comments
 (0)