The Generous Ones
A medium Python interview practice problem on DataDriven. Write the Python and run it against test cases, with instant feedback.
- Domain
- Python
- Difficulty
- medium
- Seniority
- L3
- Asked in
- Netflix
Problem
A tipping feature's log arrives as two lists aligned by position, user_ids and tips, and the same user can leave many tips across the log. Return the user whose tips add up to the most, and when totals tie, the one whose id comes first alphabetically.
The generous ones are obvious.
Example
Input:
user_ids = ["A","B","A","C"], tips = [5,3,10,8]
Output:
"A"
Worked solution and explanation
This is a group-by-key sum disguised as two flat lists. Position is an implicit join: index i in user_ids and index i in tips are one tip event. Everyone sees that a max is involved. What separates candidates is whether they take the max over totals or over rows. Take the biggest single tip, and a user with one big tip beats someone who quietly tipped more over three visits. Count entries, and a regular with small tips beats the one-time big spender. Either way you return the wrong user.
Two passes, one idea each
Step 1: Collapse rows into per-user totals
Walk the positions once, adding tips[i] onto the running total for user_ids[i]. A first appearance starts the total at that tip; a repeat adds to it. Assigning instead of adding keeps only each user's last tip, and the answer looks plausible while being wrong.
Step 2: Pick the winner from the totals, not the rows
Scan the totals once, holding the leader so far. A strictly larger total takes over. An equal total takes over only when its id sorts earlier, so the answer never depends on who happened to appear first in the log.
def biggest_tipper(user_ids: list[str], tips: list[float]) -> str:
totals = {}
for i in range(len(user_ids)):
user = user_ids[i]
if user in totals:
totals[user] += tips[i]
else:
totals[user] = tips[i]
best_user = user_ids[0]
for user, total in totals.items():
if total > totals[best_user]:
best_user = user
elif total == totals[best_user]:
# equal totals: the alphabetically first id wins, not the first seen
if user < best_user:
best_user = user
return best_user- Biggest single tip
- With 'ana' tipping 1 and 3 and 'ben' tipping 3.5, the largest row is ben's 3.5, so this returns 'ben'.
- Biggest total
- Summed, 'ana' has 4 and 'ben' has 3.5, so the answer is 'ana'. A row max never learns that ana's two tips belong together.
Common follow-up questions
- What if every user tied for the top total should be returned? (Tests collecting all maxima and deciding their order.)
- What changes if `user_ids` and `tips` can differ in length? (Tests defensive validation versus silently truncating.)
- How would you return the top three tippers instead of one? (Tests a bounded top-k over the totals instead of a full sort.)