Approach 1 — Min-Heap merging rows (O(k log n)):Idea: Treat each row as a sorted list. Push first element of each row into a min-heap (value, row, col). Pop the smallest k-1 times, and when you pop (r,c) push (r,c+1) if exists. After k-1 pops, the next pop is kth smallest.python
import heapq
def kthSmallest_heap(matrix, k):
n = len(matrix)
if n == 0 or k < 1 or k > n * n:
raise ValueError("Invalid input")
heap = []
# push first element of each row (value, row, col)
for r in range(min(n, k)): # no need to push more than k rows
heapq.heappush(heap, (matrix[r][0], r, 0))
# pop k-1 times
for _ in range(k - 1):
val, r, c = heapq.heappop(heap)
if c + 1 < n:
heapq.heappush(heap, (matrix[r][c + 1], r, c + 1))
return heapq.heappop(heap)[0]
Approach 2 — Binary search on value range (O(n log(range))):Idea: Use value-range binary search between smallest and largest elements. For mid, count how many elements <= mid using row-wise binary search (or two-pointer from bottom-left in O(n)). If count < k move right, else move left. Continue until low is kth smallest.python
import bisect
def kthSmallest_bs(matrix, k):
n = len(matrix)
if n == 0 or k < 1 or k > n * n:
raise ValueError("Invalid input")
low, high = matrix[0][0], matrix[-1][-1]
while low < high:
mid = (low + high) // 2
# count <= mid using bisect on each row
cnt = 0
for row in matrix:
cnt += bisect.bisect_right(row, mid)
if cnt < k:
low = mid + 1
else:
high = mid
return low
Key points and trade-offs:- Heap: O(k log min(n,k)) time, O(min(n,k)) space. Simple, returns exact element by order. Good when k is small relative to n (e.g., k << n^2) or when matrix values range is huge/unknown.- Binary search: Each count is O(n log n) if using bisect per row, or O(n) with two-pointer, so total O(n log(range)) where range = max-min. Uses O(1) extra space. Prefer when n is moderate and k large (near n^2) or when matrix is large but value range is small or comparisons are cheap.- Binary search is faster when k is large or when range is small; heap is better when k is small or you need actual streaming/online retrieval of first k elements.Edge cases: empty matrix, k out of bounds, duplicate values (both handle correctly).