Sign in to run and submit your work
Reading is open to everyone. Running code and saving drafts need an account so your work is yours and comes back on your next visit.
or
CODE WORKSPACE
Two warehouses each export the customer ids they shipped to last week, and each export arrives sorted ascending. Finance wants the customers served by both warehouses. The exports are not clean sets: when a customer's record was touched twice, the export lists that id twice.
Write common_ids(export_a, export_b). It takes two lists of integer customer ids, each sorted ascending and each possibly containing repeats, and returns the ascending list of ids that appear in both lists, with every id listed once.
Function to write
common_ids(export_a: list[int], export_b: list[int]) -> list[int]An ascending list of the customer ids present in both exports, each id once.
How to approach it
Keep one index per export and always advance the one pointing at the smaller id; when they match, only record the id if it differs from the last one you kept.
Sample cases
+ 2 held back until you submit
a shared id exported twice
104 appears twice in both exports but must come back once — the duplicate-output trap.
Input
Argument 1
[
101,
104,
104,
107,
112
]Argument 2
[
104,
104,
109,
112,
120
]Returns
[
104,
112
]no customer in common
The exports interleave without ever matching, so the answer is an empty list.
Input
Argument 1
[
3,
5,
9
]Argument 2
[
4,
6,
10
]Returns
[] (empty list)
one warehouse exported nothing
An empty export shares nothing with anything; return [] without indexing into it.
Input
Argument 1
[] (empty list)
Argument 2
[
7,
8
]Returns
[] (empty list)
one export is much shorter
The only match is the very last id, so the walk must keep going until one list runs out.
Input
Argument 1
[
2,
4,
6,
8,
10,
12
]Argument 2
[
1,
12
]Returns
[
12
]Constraints
export_a and export_b are lists of integers, each already sorted ascending. Either may contain the same id more than once.[] — not None.Worked example
Take export_a = [101, 104, 104, 107, 112] and export_b = [104, 104, 109, 112, 120]. Put one pointer at the start of each. 101 against 104: 101 is smaller, and export_b only grows from here, so 101 can never match — advance the first pointer. 104 against 104: a match, record 104 and advance both. 104 against 104 again: a match, but 104 is already the last id recorded, so skip it and advance both. 107 against 109: advance the first. 112 against 109: advance the second. 112 against 112: record 112. export_a is used up, so stop. The result is [104, 112].
The trap: filtering export_a with if customer in export_b returns [104, 104, 112] on the same input, because 104 is exported twice.
What this tests
The two pointers merge walk. This is LeetCode 'Intersection of Two Arrays' (349) in data clothing, solved the sorted way. It is not a named question in the data engineering interview reports we could find; it is the two-pointer warm-up the rest of this pattern builds on. The target is O(n + m) time and O(1) extra memory beyond the output. Building a set of one export also runs in O(n + m), but it holds a whole export in memory and throws away the ordering you were given for free; in against a list inside a loop is O(n·m). The walk only works because both inputs are sorted — a smaller value can be discarded because nothing later in the other list can equal it. It is the same logic as a database sort-merge join, and it is what you reach for when two systems hand you large, already-sorted exports.
common_ids(export_a: list[int], export_b: list[int]) -> list[int]Submit for review to find out what your query gets right, what it gets wrong, and how it compares with the best working query for this exercise.
This scenario runs a full workspace — editor, canvas and results side by side. It needs a laptop or desktop to be usable. Open this page on a bigger screen to start building.