Skip to content

Commit 27cf110

Browse files
committed
add 9 solutions
1 parent 9a7155e commit 27cf110

File tree

13 files changed

+1821
-13
lines changed

13 files changed

+1821
-13
lines changed

src/.vuepress/public/.htaccess

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
RewriteEngine On
2+
3+
# Redirect leetcode paths
4+
RewriteRule ^leetcode-js/leetcode/(.*)$ /leetcode-js/$1 [R=301,L]
5+
6+
# Redirect blog paths
7+
RewriteRule ^leetcode-js/blog/(.*)$ /blog/$1 [R=301,L]
8+
9+
# Redirect react paths
10+
RewriteRule ^leetcode-js/react/(.*)$ /my-react/$1 [R=301,L]
11+
12+
# Redirect vue paths
13+
RewriteRule ^leetcode-js/vue/(.*)$ /my-vue/$1 [R=301,L]

src/.vuepress/sidebar.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ export default sidebar({
177177
"0172",
178178
"0173",
179179
"0174",
180+
"0183",
180181
"0188",
181182
"0189",
182183
"0190",
@@ -326,7 +327,8 @@ export default sidebar({
326327
"0572",
327328
"0583",
328329
"0589",
329-
"0590"
330+
"0590",
331+
"0595"
330332
]
331333
},
332334
{
@@ -435,6 +437,7 @@ export default sidebar({
435437
"1106",
436438
"1137",
437439
"1143",
440+
"1148",
438441
"1161",
439442
"1190"
440443
]
@@ -484,7 +487,9 @@ export default sidebar({
484487
"text": "1500-1599",
485488
"collapsible": true,
486489
"children": [
490+
"1517",
487491
"1522",
492+
"1527",
488493
"1545",
489494
"1574",
490495
"1590",
@@ -497,15 +502,18 @@ export default sidebar({
497502
"children": [
498503
"1652",
499504
"1657",
505+
"1667",
500506
"1671",
501-
"1679"
507+
"1679",
508+
"1683"
502509
]
503510
},
504511
{
505512
"text": "1700-1799",
506513
"collapsible": true,
507514
"children": [
508515
"1732",
516+
"1757",
509517
"1760",
510518
"1768"
511519
]
@@ -516,7 +524,8 @@ export default sidebar({
516524
"children": [
517525
"1813",
518526
"1829",
519-
"1861"
527+
"1861",
528+
"1873"
520529
]
521530
},
522531
{

src/problem/0183.md

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
---
2+
title: 183. 从不订购的客户
3+
description: LeetCode 183. 从不订购的客户题解,Customers Who Never Order,包含解题思路、复杂度分析以及完整的 JavaScript 代码实现。
4+
keywords:
5+
- LeetCode
6+
- 183. 从不订购的客户
7+
- 从不订购的客户
8+
- Customers Who Never Order
9+
- 解题思路
10+
- 数据库
11+
---
12+
13+
# 183. 从不订购的客户
14+
15+
🟢 <font color=#15bd66>Easy</font>&emsp; 🔖&ensp; [`数据库`](/tag/database.md)&emsp; 🔗&ensp;[`力扣`](https://leetcode.cn/problems/customers-who-never-order) [`LeetCode`](https://leetcode.com/problems/customers-who-never-order)
16+
17+
## 题目
18+
19+
Table: `Customers`
20+
21+
> ```
22+
> +-------------+---------+
23+
> | Column Name | Type |
24+
> +-------------+---------+
25+
> | id | int |
26+
> | name | varchar |
27+
> +-------------+---------+
28+
> ```
29+
>
30+
> id is the primary key (column with unique values) for this table.
31+
>
32+
> Each row of this table indicates the ID and name of a customer.
33+
34+
Table: `Orders`
35+
36+
> ```
37+
> +-------------+------+
38+
> | Column Name | Type |
39+
> +-------------+------+
40+
> | id | int |
41+
> | customerId | int |
42+
> +-------------+------+
43+
> ```
44+
>
45+
> id is the primary key (column with unique values) for this table.
46+
>
47+
> customerId is a foreign key (reference columns) of the ID from the Customers table.
48+
>
49+
> Each row of this table indicates the ID of an order and the ID of the customer who ordered it.
50+
51+
Write a solution to find all customers who never order anything.
52+
53+
Return the result table in **any order**.
54+
55+
The result format is in the following example.
56+
57+
**Example 1:**
58+
59+
> Input:
60+
>
61+
> Customers table:
62+
>
63+
> ```
64+
> +----+-------+
65+
> | id | name |
66+
> +----+-------+
67+
> | 1 | Joe |
68+
> | 2 | Henry |
69+
> | 3 | Sam |
70+
> | 4 | Max |
71+
> +----+-------+
72+
> ```
73+
>
74+
> Orders table:
75+
>
76+
> ```
77+
> +----+------------+
78+
> | id | customerId |
79+
> +----+------------+
80+
> | 1 | 3 |
81+
> | 2 | 1 |
82+
> +----+------------+
83+
> ```
84+
>
85+
> Output:
86+
>
87+
> ```
88+
> +-----------+
89+
> | Customers |
90+
> +-----------+
91+
> | Henry |
92+
> | Max |
93+
> +-----------+
94+
> ```
95+
96+
## 题目大意
97+
98+
`Customers` 表:
99+
100+
> ```
101+
> +-------------+---------+
102+
> | Column Name | Type |
103+
> +-------------+---------+
104+
> | id | int |
105+
> | name | varchar |
106+
> +-------------+---------+
107+
> ```
108+
>
109+
> 在 SQL 中,id 是该表的主键。
110+
>
111+
> 该表的每一行都表示客户的 ID 和名称。
112+
113+
`Orders` 表:
114+
115+
> ```
116+
> +-------------+------+
117+
> | Column Name | Type |
118+
> +-------------+------+
119+
> | id | int |
120+
> | customerId | int |
121+
> +-------------+------+
122+
> ```
123+
>
124+
> 在 SQL 中,id 是该表的主键。
125+
>
126+
> customerId 是 Customers 表中 ID 的外键( Pandas 中的连接键)。
127+
>
128+
> 该表的每一行都表示订单的 ID 和订购该订单的客户的 ID。
129+
130+
找出所有从不点任何东西的顾客。
131+
132+
以 **任意顺序** 返回结果表。
133+
134+
结果格式如下所示。
135+
136+
**示例 1:**
137+
138+
> **输入:**
139+
>
140+
> Customers table:
141+
>
142+
> ```
143+
> +----+-------+
144+
> | id | name |
145+
> +----+-------+
146+
> | 1 | Joe |
147+
> | 2 | Henry |
148+
> | 3 | Sam |
149+
> | 4 | Max |
150+
> +----+-------+
151+
> ```
152+
>
153+
> Orders table:
154+
>
155+
> ```
156+
> +----+------------+
157+
> | id | customerId |
158+
> +----+------------+
159+
> | 1 | 3 |
160+
> | 2 | 1 |
161+
> +----+------------+
162+
> ```
163+
>
164+
> **输出:**
165+
>
166+
> ```
167+
> +-----------+
168+
> | Customers |
169+
> +-----------+
170+
> | Henry |
171+
> | Max |
172+
> +-----------+
173+
> ```
174+
175+
## 解题思路
176+
177+
### MySQL
178+
179+
1. **返回字段**:
180+
`SELECT` 指定要返回的字段:`name`(客户名称),重命名为 `Customers`。
181+
`FROM Customers` 表作为数据来源。
182+
183+
2. **筛选条件**:
184+
- 使用 `LEFT JOIN` 将 `Customers` 表与 `Orders` 表连接,关联条件是 `Customers.id = Orders.customerId`。
185+
- 筛选出未下单的客户,即 `Orders.customerId` 为 `NULL` 的记录。
186+
- 使用 `WHERE o.customerId IS NULL` 筛选条件。
187+
188+
#### 复杂度分析
189+
190+
- **时间复杂度**:`O(n + m)`,其中 `n` 是 `Customers` 表的记录数,`m` 是 `Orders` 表的记录数。
191+
- **空间复杂度**:返回的结果占用的空间与未下单的客户数成正比。
192+
193+
---
194+
195+
### Pandas
196+
197+
1. **加载数据**:
198+
将 `Customers` 和 `Orders` 数据加载到 Pandas 的两个 `DataFrame` 中。
199+
200+
2. **左连接**:
201+
使用 `merge` 模拟 SQL 的 `LEFT JOIN`,`Customers` 为左表,`Orders` 为右表,关联条件是 `Customers.id = Orders.customerId`。
202+
203+
3. **筛选条件**:
204+
筛选出 `customerId` 为 `NaN` 的记录,即未下过订单的客户。
205+
206+
4. **选择列**:
207+
保留筛选后的 `name` 列,并重命名为 `Customers` ,作为最终结果。
208+
209+
## 代码
210+
211+
::: code-tabs
212+
@tab MySQL
213+
214+
```sql
215+
SELECT c.name as Customers
216+
FROM Customers c
217+
LEFT JOIN Orders o
218+
ON c.id = o.customerId
219+
WHERE o.customerId IS NULL
220+
```
221+
222+
@tab Pandas
223+
224+
```python
225+
import pandas as pd
226+
227+
def customers_without_orders(customers: pd.DataFrame, orders: pd.DataFrame) -> pd.DataFrame:
228+
# LEFT JOIN 模拟
229+
merged = pd.merge(customers, orders, left_on='id', right_on='customerId', how='left')
230+
# 筛选未下订单的客户
231+
return merged[merged['customerId'].isna()][['name']].rename(columns={'name': 'Customers'})
232+
```
233+
234+
:::

0 commit comments

Comments
 (0)