diff --git a/.prettierignore b/.prettierignore index 05bf32e478051..13715bc116db8 100644 --- a/.prettierignore +++ b/.prettierignore @@ -25,3 +25,4 @@ node_modules/ /solution/2200-2299/2253.Dynamic Unpivoting of a Table/Solution.sql /solution/3100-3199/3150.Invalid Tweets II/Solution.sql /solution/3100-3199/3198.Find Cities in Each State/Solution.sql +/solution/3300-3399/3328.Find Cities in Each State II/Solution.sql diff --git a/solution/3300-3399/3328.Find Cities in Each State II/README.md b/solution/3300-3399/3328.Find Cities in Each State II/README.md new file mode 100644 index 0000000000000..7ff0db455e066 --- /dev/null +++ b/solution/3300-3399/3328.Find Cities in Each State II/README.md @@ -0,0 +1,193 @@ +--- +comments: true +difficulty: 中等 +edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3328.Find%20Cities%20in%20Each%20State%20II/README.md +tags: + - 数据库 +--- + + + +# [3328. Find Cities in Each State II 🔒](https://leetcode.cn/problems/find-cities-in-each-state-ii) + +[English Version](/solution/3300-3399/3328.Find%20Cities%20in%20Each%20State%20II/README_EN.md) + +## 题目描述 + + + +

Table: cities

+ +
++-------------+---------+
+| Column Name | Type    |
++-------------+---------+
+| state       | varchar |
+| city        | varchar |
++-------------+---------+
+(state, city) is the combination of columns with unique values for this table.
+Each row of this table contains the state name and the city name within that state.
+
+ +

Write a solution to find all the cities in each state and analyze them based on the following requirements:

+ + + +

Return the result table ordered by the count of matching-letter cities in descending order and then by state name in ascending order.

+ +

The result format is in the following example.

+ +

 

+

Example:

+ +
+

Input:

+ +

cities table:

+ +
++--------------+---------------+
+| state        | city          |
++--------------+---------------+
+| New York     | New York City |
+| New York     | Newark        |
+| New York     | Buffalo       |
+| New York     | Rochester     |
+| California   | San Francisco |
+| California   | Sacramento    |
+| California   | San Diego     |
+| California   | Los Angeles   |
+| Texas        | Tyler         |
+| Texas        | Temple        |
+| Texas        | Taylor        |
+| Texas        | Dallas        |
+| Pennsylvania | Philadelphia  |
+| Pennsylvania | Pittsburgh    |
+| Pennsylvania | Pottstown     |
++--------------+---------------+
+
+ +

Output:

+ +
++-------------+-------------------------------------------+-----------------------+
+| state       | cities                                    | matching_letter_count |
++-------------+-------------------------------------------+-----------------------+
+| Pennsylvania| Philadelphia, Pittsburgh, Pottstown       | 3                     |
+| Texas       | Dallas, Taylor, Temple, Tyler             | 2                     |
+| New York    | Buffalo, Newark, New York City, Rochester | 2                     |
++-------------+-------------------------------------------+-----------------------+
+
+ +

Explanation:

+ + + +

Note:

+ + +
+ + + +## 解法 + + + +### 方法一:分组聚合 + 过滤 + +我们可以将 `cities` 表按照 `state` 字段进行分组聚合,然后对每个分组进行过滤,筛选出满足条件的分组。 + + + +#### MySQL + +```sql +# Write your MySQL query statement below +SELECT + state, + GROUP_CONCAT(city ORDER BY city SEPARATOR ', ') AS cities, + COUNT( + CASE + WHEN LEFT(city, 1) = LEFT(state, 1) THEN 1 + END + ) AS matching_letter_count +FROM cities +GROUP BY 1 +HAVING COUNT(city) >= 3 AND matching_letter_count > 0 +ORDER BY 3 DESC, 1; +``` + +#### Pandas + +```python +import pandas as pd + + +def state_city_analysis(cities: pd.DataFrame) -> pd.DataFrame: + cities["matching_letter"] = cities["city"].str[0] == cities["state"].str[0] + + result = ( + cities.groupby("state") + .agg( + cities=("city", lambda x: ", ".join(sorted(x))), + matching_letter_count=("matching_letter", "sum"), + city_count=("city", "count"), + ) + .reset_index() + ) + + result = result[(result["city_count"] >= 3) & (result["matching_letter_count"] > 0)] + + result = result.sort_values( + by=["matching_letter_count", "state"], ascending=[False, True] + ) + + result = result.drop(columns=["city_count"]) + + return result +``` + + + + + + diff --git a/solution/3300-3399/3328.Find Cities in Each State II/README_EN.md b/solution/3300-3399/3328.Find Cities in Each State II/README_EN.md new file mode 100644 index 0000000000000..f1eab9077e28c --- /dev/null +++ b/solution/3300-3399/3328.Find Cities in Each State II/README_EN.md @@ -0,0 +1,193 @@ +--- +comments: true +difficulty: Medium +edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3328.Find%20Cities%20in%20Each%20State%20II/README_EN.md +tags: + - Database +--- + + + +# [3328. Find Cities in Each State II 🔒](https://leetcode.com/problems/find-cities-in-each-state-ii) + +[中文文档](/solution/3300-3399/3328.Find%20Cities%20in%20Each%20State%20II/README.md) + +## Description + + + +

Table: cities

+ +
++-------------+---------+
+| Column Name | Type    |
++-------------+---------+
+| state       | varchar |
+| city        | varchar |
++-------------+---------+
+(state, city) is the combination of columns with unique values for this table.
+Each row of this table contains the state name and the city name within that state.
+
+ +

Write a solution to find all the cities in each state and analyze them based on the following requirements:

+ + + +

Return the result table ordered by the count of matching-letter cities in descending order and then by state name in ascending order.

+ +

The result format is in the following example.

+ +

 

+

Example:

+ +
+

Input:

+ +

cities table:

+ +
++--------------+---------------+
+| state        | city          |
++--------------+---------------+
+| New York     | New York City |
+| New York     | Newark        |
+| New York     | Buffalo       |
+| New York     | Rochester     |
+| California   | San Francisco |
+| California   | Sacramento    |
+| California   | San Diego     |
+| California   | Los Angeles   |
+| Texas        | Tyler         |
+| Texas        | Temple        |
+| Texas        | Taylor        |
+| Texas        | Dallas        |
+| Pennsylvania | Philadelphia  |
+| Pennsylvania | Pittsburgh    |
+| Pennsylvania | Pottstown     |
++--------------+---------------+
+
+ +

Output:

+ +
++-------------+-------------------------------------------+-----------------------+
+| state       | cities                                    | matching_letter_count |
++-------------+-------------------------------------------+-----------------------+
+| Pennsylvania| Philadelphia, Pittsburgh, Pottstown       | 3                     |
+| Texas       | Dallas, Taylor, Temple, Tyler             | 2                     |
+| New York    | Buffalo, Newark, New York City, Rochester | 2                     |
++-------------+-------------------------------------------+-----------------------+
+
+ +

Explanation:

+ + + +

Note:

+ + +
+ + + +## Solutions + + + +### Solution 1: Group Aggregation + Filtering + +We can group the `cities` table by the `state` field, then apply filtering on each group to retain only the groups that meet the specified conditions. + + + +#### MySQL + +```sql +# Write your MySQL query statement below +SELECT + state, + GROUP_CONCAT(city ORDER BY city SEPARATOR ', ') AS cities, + COUNT( + CASE + WHEN LEFT(city, 1) = LEFT(state, 1) THEN 1 + END + ) AS matching_letter_count +FROM cities +GROUP BY 1 +HAVING COUNT(city) >= 3 AND matching_letter_count > 0 +ORDER BY 3 DESC, 1; +``` + +#### Pandas + +```python +import pandas as pd + + +def state_city_analysis(cities: pd.DataFrame) -> pd.DataFrame: + cities["matching_letter"] = cities["city"].str[0] == cities["state"].str[0] + + result = ( + cities.groupby("state") + .agg( + cities=("city", lambda x: ", ".join(sorted(x))), + matching_letter_count=("matching_letter", "sum"), + city_count=("city", "count"), + ) + .reset_index() + ) + + result = result[(result["city_count"] >= 3) & (result["matching_letter_count"] > 0)] + + result = result.sort_values( + by=["matching_letter_count", "state"], ascending=[False, True] + ) + + result = result.drop(columns=["city_count"]) + + return result +``` + + + + + + diff --git a/solution/3300-3399/3328.Find Cities in Each State II/Solution.py b/solution/3300-3399/3328.Find Cities in Each State II/Solution.py new file mode 100644 index 0000000000000..3c33145d67547 --- /dev/null +++ b/solution/3300-3399/3328.Find Cities in Each State II/Solution.py @@ -0,0 +1,25 @@ +import pandas as pd + + +def state_city_analysis(cities: pd.DataFrame) -> pd.DataFrame: + cities["matching_letter"] = cities["city"].str[0] == cities["state"].str[0] + + result = ( + cities.groupby("state") + .agg( + cities=("city", lambda x: ", ".join(sorted(x))), + matching_letter_count=("matching_letter", "sum"), + city_count=("city", "count"), + ) + .reset_index() + ) + + result = result[(result["city_count"] >= 3) & (result["matching_letter_count"] > 0)] + + result = result.sort_values( + by=["matching_letter_count", "state"], ascending=[False, True] + ) + + result = result.drop(columns=["city_count"]) + + return result diff --git a/solution/3300-3399/3328.Find Cities in Each State II/Solution.sql b/solution/3300-3399/3328.Find Cities in Each State II/Solution.sql new file mode 100644 index 0000000000000..ce985e262d394 --- /dev/null +++ b/solution/3300-3399/3328.Find Cities in Each State II/Solution.sql @@ -0,0 +1,13 @@ +# Write your MySQL query statement below +SELECT + state, + GROUP_CONCAT(city ORDER BY city SEPARATOR ', ') AS cities, + COUNT( + CASE + WHEN LEFT(city, 1) = LEFT(state, 1) THEN 1 + END + ) AS matching_letter_count +FROM cities +GROUP BY 1 +HAVING COUNT(city) >= 3 AND matching_letter_count > 0 +ORDER BY 3 DESC, 1; diff --git a/solution/DATABASE_README.md b/solution/DATABASE_README.md index c396c38a3b2ad..c90cbda654bbf 100644 --- a/solution/DATABASE_README.md +++ b/solution/DATABASE_README.md @@ -298,6 +298,7 @@ | 3293 | [计算产品最终价格](/solution/3200-3299/3293.Calculate%20Product%20Final%20Price/README.md) | `数据库` | 中等 | 🔒 | | 3308 | [Find Top Performing Driver](/solution/3300-3399/3308.Find%20Top%20Performing%20Driver/README.md) | `数据库` | 中等 | 🔒 | | 3322 | [英超积分榜排名 III](/solution/3300-3399/3322.Premier%20League%20Table%20Ranking%20III/README.md) | `数据库` | 中等 | 🔒 | +| 3328 | [Find Cities in Each State II](/solution/3300-3399/3328.Find%20Cities%20in%20Each%20State%20II/README.md) | | 中等 | 🔒 | ## 版权 diff --git a/solution/DATABASE_README_EN.md b/solution/DATABASE_README_EN.md index 0ad562b350bea..46112987e16f6 100644 --- a/solution/DATABASE_README_EN.md +++ b/solution/DATABASE_README_EN.md @@ -296,6 +296,7 @@ Press Control + F(or Command + F on | 3293 | [Calculate Product Final Price](/solution/3200-3299/3293.Calculate%20Product%20Final%20Price/README_EN.md) | `Database` | Medium | 🔒 | | 3308 | [Find Top Performing Driver](/solution/3300-3399/3308.Find%20Top%20Performing%20Driver/README_EN.md) | `Database` | Medium | 🔒 | | 3322 | [Premier League Table Ranking III](/solution/3300-3399/3322.Premier%20League%20Table%20Ranking%20III/README_EN.md) | `Database` | Medium | 🔒 | +| 3328 | [Find Cities in Each State II](/solution/3300-3399/3328.Find%20Cities%20in%20Each%20State%20II/README_EN.md) | | Medium | 🔒 | ## Copyright diff --git a/solution/README.md b/solution/README.md index fff63e2896af9..46544026be341 100644 --- a/solution/README.md +++ b/solution/README.md @@ -3338,6 +3338,7 @@ | 3325 | [字符至少出现 K 次的子字符串 I](/solution/3300-3399/3325.Count%20Substrings%20With%20K-Frequency%20Characters%20I/README.md) | | 中等 | 第 420 场周赛 | | 3326 | [使数组非递减的最少除法操作次数](/solution/3300-3399/3326.Minimum%20Division%20Operations%20to%20Make%20Array%20Non%20Decreasing/README.md) | | 中等 | 第 420 场周赛 | | 3327 | [判断 DFS 字符串是否是回文串](/solution/3300-3399/3327.Check%20if%20DFS%20Strings%20Are%20Palindromes/README.md) | | 困难 | 第 420 场周赛 | +| 3328 | [Find Cities in Each State II](/solution/3300-3399/3328.Find%20Cities%20in%20Each%20State%20II/README.md) | | 中等 | 🔒 | ## 版权 diff --git a/solution/README_EN.md b/solution/README_EN.md index b07d1b10a7ede..cbe04361f3fea 100644 --- a/solution/README_EN.md +++ b/solution/README_EN.md @@ -3336,6 +3336,7 @@ Press Control + F(or Command + F on | 3325 | [Count Substrings With K-Frequency Characters I](/solution/3300-3399/3325.Count%20Substrings%20With%20K-Frequency%20Characters%20I/README_EN.md) | | Medium | Weekly Contest 420 | | 3326 | [Minimum Division Operations to Make Array Non Decreasing](/solution/3300-3399/3326.Minimum%20Division%20Operations%20to%20Make%20Array%20Non%20Decreasing/README_EN.md) | | Medium | Weekly Contest 420 | | 3327 | [Check if DFS Strings Are Palindromes](/solution/3300-3399/3327.Check%20if%20DFS%20Strings%20Are%20Palindromes/README_EN.md) | | Hard | Weekly Contest 420 | +| 3328 | [Find Cities in Each State II](/solution/3300-3399/3328.Find%20Cities%20in%20Each%20State%20II/README_EN.md) | | Medium | 🔒 | ## Copyright