Welcome to Subscribe On Youtube
3328. Find Cities in Each State II 🔒
Description
Table: cities
+-++ \| state \| varchar \| \| city \| varchar \| +-++ \| state \| city \| +--++
Output:
+-+-+--+ \| Pennsylvania\| Philadelphia, Pittsburgh, Pottstown \| 3 \| \| Texas \| Dallas, Taylor, Temple, Tyler \| 3 \| \| New York \| Buffalo, Newark, New York City, Rochester \| 2 \| +-+-+-----+
Explanation:
- Pennsylvania:
- Has 3 cities (meets minimum requirement)
- All 3 cities start with 'P' (same as state)
- matching_letter_count = 3
- Texas:
- Has 4 cities (meets minimum requirement)
- 3 cities (Taylor, Temple, Tyler) start with 'T' (same as state)
- matching_letter_count = 3
- New York:
- Has 4 cities (meets minimum requirement)
- 2 cities (Newark, New York City) start with 'N' (same as state)
- matching_letter_count = 2
- California is not included in the output because:
- Although it has 4 cities (meets minimum requirement)
- No cities start with 'C' (doesn't meet the matching letter requirement)
Note:
- Results are ordered by matching_letter_count in descending order
- When matching_letter_count is the same (Texas and New York both have 2), they are ordered by state name alphabetically
- Cities in each row are ordered alphabetically
</div>
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.
-
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
-
# 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;