Kth Element of Two Sorted Arrays asks for the k-th smallest value if you merged two already-sorted arrays — without paying to merge them fully. It is a clean exercise in the two-pointer merge walk that powers merge sort, with a neat early stop.
Problem. Given two sorted arrays A and B and an integer k (1-based), return the k-th
smallest element among all values in A and B combined. Do not modify the inputs.
Example: A = [1, 3, 5], B = [2, 4, 6], k = 4. The merged order is [1, 2, 3, 4, 5, 6], so the
4th smallest is 4.
The slow way first
The obvious idea: actually merge the two arrays into one sorted list, then return index k - 1. That works and is easy to reason about, but it builds the entire merged array of size n + m and keeps walking even after the answer is known. That is O(n + m) time and O(n + m) extra space — wasteful when k is small.
The question to ask: do I really need the whole merge? No. I only need the first k values in sorted order. So I can stop the walk the instant I have taken k of them.
The idea: merge, but stop at k
Keep two pointers, i into A and j into B, each sitting on the next unconsumed value. At every step, compare the two front values and take the smaller one — advance its pointer and tick a running count. The moment count equals k, the value you just took is the answer.
The key insight: because both arrays are already sorted, the smaller of the two current fronts is always the next value in global sorted order. So the k-th value we take is exactly the k-th smallest overall — no need to look at anything past it.
Walk through it
Step through the animation. Pointer i rides array A, pointer j rides array B, and count ticks up underneath. We take 1 (from A), then 2 (from B), then 3 (from A), then 4 (from B) — and the moment count reaches k = 4, the value just taken, 4, is the answer. We never look at 5 or 6.
Pseudocode
i = j = count = 0
while both arrays still have a value:
if A[i] <= B[j]:
taken = A[i]; i += 1
else:
taken = B[j]; j += 1
count += 1
if count == k:
return taken # the kth value taken
# one array ran out: the rest are the next-smallest in order
return (A[i:] + B[j:])[k - count - 1]The Python solution
def kth(A, B, k):
i = j = count = 0
while i < len(A) and j < len(B):
if A[i] <= B[j]:
taken = A[i]
i += 1
count += 1
else:
taken = B[j]
j += 1
count += 1
if count == k:
return taken
rest = A[i:] + B[j:] # one array ran out
return rest[k - count - 1]i,jare the two read positions;counttracks how many values we have taken so far.- The
whileruns only while both arrays still have a value to compare. if A[i] <= B[j]— take fromAwhen its front is smaller or equal; otherwise take fromB.takenremembers the value we just consumed.- Lines 12–13 are the early stop: as soon as
count == k, the value just taken is the k-th smallest, so we return immediately. - If one array empties before we reach
k, the remaining values (A[i:] + B[j:]) are already in sorted order, so the answer is the(k - count - 1)-th of them.
Complexity
| Case | Time | Notes |
|---|---|---|
| Full merge then index | O(n + m) (moderate) | builds the whole merged array |
| Merge walk, stop at k (this solution) | O(k) (moderate) | takes only k values |
| Binary-search variant | O(log(n + m)) (moderate) | discard k/2 per step |
O(1) (fast)The merge walk does only k comparisons and uses O(1) extra space (just the pointers and a counter). When k is large there is a sharper trick: a binary-search variant that, on each step, discards k/2 elements from one array at a time, reaching the answer in O(log(n + m)) time. It is faster but much fiddlier to get right; the linear merge walk is the one to reach for first in an interview, then mention the log version as the optimization.
When this pattern shows up
Whenever you have two (or more) sorted sequences and need a merged result — the k-th smallest, the median, or the first k in order — think two-pointer merge walk. It is the merge step of merge sort, and the early stop ("count to k, then return") turns an O(n + m) merge into O(k).
Mind the indexing: k is 1-based here, so the answer arrives when count == k, not k - 1. And do
not forget the case where one array runs out before count reaches k — the leftover values are still
sorted, so you index straight into them.
Practice
For A = [1, 3, 5], B = [2, 4, 6], k = 4: which values get taken, and in what order, before the walk stops?
1. Why is the merge walk O(k) instead of O(n + m)?
2. At each step, which value do we take?
3. Why does the kth value taken equal the kth smallest overall?
4. What does the faster binary-search variant achieve?