LeetCode Series Problems¶
This document covers common LeetCode patterns involving pandas Series operations. These problems demonstrate practical applications of Series methods for data manipulation and analysis.
Pattern 1: Value Replacement with astype¶
LeetCode 262: Trips and Users¶
Problem: Calculate cancellation rate by converting status strings to binary values.
def trips_and_users(trips: pd.DataFrame, users: pd.DataFrame) -> pd.DataFrame:
# Filter unbanned users
banned_users = users[users['banned'] == 'Yes']['users_id']
filtered_trips = trips[
~trips['client_id'].isin(banned_users) &
~trips['driver_id'].isin(banned_users)
]
# Convert status to binary: cancelled=1, completed=0
cancelled = filtered_trips['status'].replace({
'cancelled_by_driver': 1,
'cancelled_by_client': 1,
'completed': 0
}).astype(int)
# Calculate cancellation rate
cancellation_rate = cancelled.sum() / len(cancelled)
return cancellation_rate
Key Concepts:
- replace() maps categorical values to numeric
- astype(int) ensures consistent integer type
- Series arithmetic for rate calculation
Pattern 2: Boolean Filtering with isin¶
LeetCode 183: Customers Who Never Order¶
Problem: Find customers not present in orders table.
def find_customers(customers: pd.DataFrame, orders: pd.DataFrame) -> pd.DataFrame:
# Find customers whose id is NOT in orders
no_orders = customers[~customers['id'].isin(orders['customerId'])]
return no_orders[['name']].rename(columns={'name': 'Customers'})
Key Concepts:
- isin() checks membership in another Series
- ~ negates boolean Series
- Boolean indexing filters DataFrame
Step-by-Step Breakdown¶
# Sample data
customers = pd.DataFrame({
'id': [1, 2, 3],
'name': ['Alice', 'Bob', 'Charlie']
})
orders = pd.DataFrame({'customerId': [1, 3]})
# Step 1: Check membership
mask = customers['id'].isin(orders['customerId'])
print(mask) # True, False, True
# Step 2: Negate to find non-members
mask = ~mask
print(mask) # False, True, False
# Step 3: Filter
result = customers[mask]
print(result) # Bob (id=2)
Pattern 3: Missing Value Detection with isna/isnull¶
LeetCode 608: Tree Node¶
Problem: Classify tree nodes as Root, Inner, or Leaf.
def tree_node(tree: pd.DataFrame) -> pd.DataFrame:
# Root: p_id is null
tree.loc[tree['p_id'].isna(), 'type'] = 'Root'
# Inner: has parent AND has children
has_children = tree['id'].isin(tree['p_id'])
tree.loc[has_children & tree['p_id'].notna(), 'type'] = 'Inner'
# Leaf: has parent but no children
tree.loc[~has_children & tree['p_id'].notna(), 'type'] = 'Leaf'
return tree[['id', 'type']]
Key Concepts:
- isna() detects missing values
- notna() detects non-missing values
- .loc[] for conditional assignment
LeetCode 1965: Employees With Missing Information¶
Problem: Find employees with incomplete records.
def employees_with_missing_info(
employees: pd.DataFrame,
salaries: pd.DataFrame
) -> pd.DataFrame:
# Merge with outer join
merged = employees.merge(salaries, on='employee_id', how='outer')
# Find rows with any missing value
missing = merged[merged.isna().any(axis=1)]
return missing[['employee_id']].sort_values('employee_id')
Key Concepts:
- isna() returns boolean DataFrame
- any(axis=1) checks if any column is True per row
- Boolean indexing on aggregated condition
Pattern 4: Counting with value_counts and nunique¶
LeetCode 570: Managers with 5+ Direct Reports¶
Problem: Find managers who have at least 5 direct reports.
def find_managers(employee: pd.DataFrame) -> pd.DataFrame:
# Count direct reports per manager
manager_counts = employee['managerId'].value_counts()
# Filter managers with 5+ reports
qualified = manager_counts[manager_counts >= 5].index
# Get manager names
return employee[employee['id'].isin(qualified)][['name']]
Key Concepts:
- value_counts() counts occurrences
- Index contains unique values
- Filter on count threshold
LeetCode 550: Game Play Analysis IV¶
Problem: Calculate fraction of players who logged in on consecutive days.
def game_play_analysis(activity: pd.DataFrame) -> pd.DataFrame:
# Get first login date per player
first_login = activity.groupby('player_id')['event_date'].min()
# Count total unique players
total_players = activity['player_id'].nunique()
# Check for next-day login
activity['first_date'] = activity['player_id'].map(first_login)
activity['next_day'] = activity['first_date'] + pd.Timedelta(days=1)
# Count players with next-day login
next_day_logins = activity[
activity['event_date'] == activity['next_day']
]['player_id'].nunique()
fraction = next_day_logins / total_players
return pd.DataFrame({'fraction': [round(fraction, 2)]})
Key Concepts:
- nunique() counts unique values
- groupby().min() finds first occurrence
- Date arithmetic with Timedelta
Pattern 5: String Operations¶
LeetCode 1667: Fix Names in a Table¶
Problem: Capitalize first letter, lowercase rest.
def fix_names(users: pd.DataFrame) -> pd.DataFrame:
users['name'] = users['name'].str.capitalize()
return users.sort_values('user_id')
LeetCode 1683: Invalid Tweets¶
Problem: Find tweets with content > 15 characters.
def invalid_tweets(tweets: pd.DataFrame) -> pd.DataFrame:
return tweets[tweets['content'].str.len() > 15][['tweet_id']]
LeetCode 1873: Calculate Special Bonus¶
Problem: Bonus for employees with odd ID and name not starting with 'M'.
def calculate_special_bonus(employees: pd.DataFrame) -> pd.DataFrame:
# Condition: odd ID AND name doesn't start with M
condition = (
(employees['employee_id'] % 2 != 0) &
(~employees['name'].str.startswith('M'))
)
# Assign bonus
employees['bonus'] = 0
employees.loc[condition, 'bonus'] = employees.loc[condition, 'salary']
return employees[['employee_id', 'bonus']].sort_values('employee_id')
LeetCode 1517: Find Users With Valid E-Mails¶
Problem: Filter users with valid email format.
def valid_emails(users: pd.DataFrame) -> pd.DataFrame:
pattern = r'^[A-Za-z][A-Za-z0-9_.\-]*@leetcode\.com$'
valid = users[users['mail'].str.match(pattern)]
return valid
LeetCode 620: Not Boring Movies¶
Problem: Find movies with odd ID and description not containing "boring".
def not_boring_movies(cinema: pd.DataFrame) -> pd.DataFrame:
condition = (
(cinema['id'] % 2 != 0) &
(~cinema['description'].str.contains('boring', case=False))
)
return cinema[condition].sort_values('rating', ascending=False)
Pattern 6: Value Replacement¶
LeetCode 627: Swap Salary¶
Problem: Swap 'm' and 'f' values in sex column.
def swap_salary(salary: pd.DataFrame) -> pd.DataFrame:
salary['sex'] = salary['sex'].replace({'m': 'f', 'f': 'm'})
return salary
Key Concepts:
- replace() with dictionary for bidirectional swap
- In-place modification of column
Pattern 7: Rolling Window¶
LeetCode 1321: Restaurant Growth¶
Problem: Calculate 7-day rolling sum of amounts.
def restaurant_growth(customer: pd.DataFrame) -> pd.DataFrame:
# Group by date and sum amounts
daily = customer.groupby('visited_on')['amount'].sum().reset_index()
# Set date as index for rolling
daily = daily.set_index('visited_on').sort_index()
# Calculate 7-day rolling sum
daily['rolling_sum'] = daily['amount'].rolling('7D').sum()
# Filter to rows with full 7-day window
# (at least 7 days from first date)
min_date = daily.index.min() + pd.Timedelta(days=6)
result = daily[daily.index >= min_date].reset_index()
return result[['visited_on', 'rolling_sum']]
Key Concepts:
- rolling('7D') creates time-based window
- Requires DatetimeIndex
- .sum() aggregates within window
Pattern 8: Aggregation to DataFrame¶
LeetCode 619: Biggest Single Number¶
Problem: Find the largest number that appears only once.
def biggest_single_number(my_numbers: pd.DataFrame) -> pd.DataFrame:
# Find numbers appearing exactly once
counts = my_numbers['num'].value_counts()
unique = counts[counts == 1].index
# Get max or None
if len(unique) > 0:
result = my_numbers[my_numbers['num'].isin(unique)]['num'].max()
else:
result = None
return pd.DataFrame({'num': [result]})
Alternative using to_frame():
def biggest_single_number(my_numbers: pd.DataFrame) -> pd.DataFrame:
unique = my_numbers.drop_duplicates(keep=False)
return unique['num'].max().to_frame(name='num') if len(unique) > 0 \
else pd.DataFrame({'num': [None]})
Pattern Summary¶
| Pattern | Methods Used | Common Use Case |
|---|---|---|
| Value Replacement | replace(), astype() |
Encoding categories |
| Boolean Filtering | isin(), ~ |
Set membership |
| Missing Detection | isna(), notna(), any() |
Data quality |
| Counting | value_counts(), nunique() |
Frequency analysis |
| String Operations | str.capitalize(), str.contains() |
Text processing |
| Rolling Windows | rolling(), sum() |
Time series |
| Aggregation | to_frame(), reset_index() |
Result formatting |