The Ones That Come Back
An easy Python interview practice problem on DataDriven. Write the Python and run it against test cases, with instant feedback.
- Domain
- Python
- Difficulty
- easy
- Seniority
- L3
- Asked in
- JPMorgan Chase
Problem
A data-quality check on an event export turned up a column of integer ids that should be unique but isn't. Return the id values that appear more than once, from smallest to largest.
In a column that promised uniqueness, some values kept their seat. Name them.
Example 1
Input:
ids = [1,2,3,2,4,3,5]
Output:
[2,3]
Example 2
Input:
ids = [5,3,5,3,3,1,1]
Output:
[1,3,5]
Worked solution and explanation
What this really is
Strip the event-export framing and this is a frequency tally with two twists. The skill being probed: count how many times each value occurs, then keep only the values whose count crosses two. Anyone can spot that a value repeats. What separates candidates is the value that repeats THREE times (it still appears once) and the promised ascending order (a bare set hands you neither). Return list(some_set) and you pass the sample by luck and fail the moment the duplicates don't happen to fall out sorted.
The tempting wrong turn
The classic "find duplicates" pattern is two sets: one for values you've seen, one for values you've seen twice. It's clean and it's O(n). But it answers a different question than the one asked here, and it quietly drops the ordering promise.
- Two sets, returned raw
- seen = set(); dups = set() for x in ids: if x in seen: dups.add(x) else: seen.add(x) return list(dups) Correctly finds duplicates, but list(dups) is in set iteration order, not ascending. On [5,3,5,3,3,1,1] it can return [3,5,1]. Contract violated.
- Count, filter, sort
- counts = Counter(ids) repeated = [] for v, c in counts.items(): if c > 1: repeated.append(v) return sorted(repeated) Tallies every value, keeps those seen more than once, and the sorted() makes the ascending contract explicit. Each value appears once because dict keys are unique.
The solution
Step 1: Tally occurrences in one pass
collections.Counter(ids) walks the list once and gives you value -> count. This is the move that separates duplicates from singletons; without a count you cannot tell them apart.
Step 2: Keep only the repeats
Loop over the counter's items and, with a simple count > 1 check, append the values that qualify. Because you're reading dict keys, each qualifying value is considered exactly once, so a thrice-seen value can't sneak in twice.
Step 3: Sort ascending on the way out
Wrap the collected values in sorted(). This is the line the naive two-set version forgets, and it's the one the grader checks.
from collections import Counter
def find_duplicates_only(ids: list[int]) -> list[int]:
counts = Counter(ids)
repeated = []
for value, count in counts.items():
if count > 1:
repeated.append(value)
return sorted(repeated)Common follow-up questions
- What if the output had to be in first-seen order instead of ascending? (Tests whether they'd swap sorted() for a first-occurrence dict, since Counter already preserves insertion order in modern Python.)
- How would you return values that appear exactly k times? (Tests generalizing the count > 1 filter to count == k with a full frequency map.)
- If the input were already sorted, could you avoid the counter entirely? (Tests recognizing that adjacent equality makes duplicates detectable in O(1) extra space.)