Back to Arrays
Q52Question 52 of 109

Kth Smallest Element in a Sorted Matrix (Row and Column Sorted Matrix)

Key Concepts
  • Each row of the matrix is a sorted list, making this a K-way Merge over N rows.
  • The heap entry stores the value, the row, and the column to locate the next element.
  • Pop K times from the min-heap to find the Kth smallest element.
  • Only the row-sorted property is required for correctness; column-sorted is a bonus.
  • Time complexity is O(K log N) and space is O(N) for the heap.
  • An alternative binary search approach on the value range achieves O(N log(max-min)) time.

Definition

Treat each row as a sorted list, run K-way Merge across rows, and stop at the Kth pop.
  • Kth Smallest in a Sorted Matrix treats each row as a sorted list and applies early-stopped K-way Merge.
  • A min-heap is seeded with the first element of each row, carrying {value, row, col}.
  • We pop K times, pushing the next column element from the same row after each pop.
  • The Kth popped value is the answer.
  • Only the row-sorted property is needed; column-sorted is not required for this approach.
  • Time is O(K log N) and space is O(N) for an N-by-N matrix.

The National Bank of India keeps a grid of service fees where each row and column increases. To find the Kth cheapest fee for a pricing tier boundary, a clerk starts with the leftmost fee of every row on a tray, pops the cheapest, and slides one step right in that same row. After K pops, the last fee removed is the Kth cheapest.

Understanding the Concepts

What is the Kth Smallest in a Sorted Matrix problem?

Given an N-by-N matrix where each row and each column is sorted in ascending order, find the Kth smallest element overall. This combines the concepts of matrix traversal and priority-based selection.

For example, given the matrix [[1, 5, 9], [10, 11, 13], [12, 13, 15]] and K = 8, the sorted order is [1, 5, 9, 10, 11, 12, 13, 13, 15], so the 8th smallest is 13.

How does the K-way Merge approach work?

Since each row is already sorted, the matrix is essentially N sorted lists. We use a min-heap seeded with the first element (column 0) of each row. The heap entry stores {value, row, col}. We pop K times, and after each pop we push the next element from the same row (column + 1) if it exists.

JAVA
package com.bank.service;

import java.util.PriorityQueue;

public class KthSmallestMatrixService {

    /**
     * Finds the Kth smallest fee in the National Bank of India fee grid.
     * Each row and column of the grid is sorted in ascending order.
     */
    public static int kthSmallest(int[][] feeGrid, int k) {
        int n = feeGrid.length;
        // Heap entry: {value, row, col}
        PriorityQueue<int[]> minHeap = new PriorityQueue<>(
            (a, b) -> Integer.compare(a[0], b[0]));

        // Seed with column 0 of each row
        for (int r = 0; r < n; r++) {
            minHeap.offer(new int[]{feeGrid[r][0], r, 0});
        }

        int result = 0;
        for (int i = 0; i < k; i++) {
            int[] entry = minHeap.poll();
            result = entry[0];
            int row = entry[1], col = entry[2];

            // Push next element from the same row
            if (col + 1 < n) {
                minHeap.offer(new int[]{feeGrid[row][col + 1], row, col + 1});
            }
        }
        return result;
    }

    public static void main(String[] args) {
        int[][] feeGrid = {
            {100, 500, 900},
            {200, 600, 1000},
            {400, 700, 1100}
        };
        int k = 5;
        System.out.println("Kth smallest fee (K=" + k + "): "
            + kthSmallest(feeGrid, k));
    }
}
BASH
javac -d out com/bank/service/KthSmallestMatrixService.java
java -cp out com.bank.service.KthSmallestMatrixService
TEXT
Kth smallest fee (K=5): 600

Why is only the row-sorted property needed?

The K-way merge treats each row as an independent sorted list. It does not use the column-sorted property at all. The column-sorted property is a nice bonus the problem gives, but the heap merge depends only on each row being sorted so that the next element in a row is always greater than or equal to the current one.

This is an important point interviewers like to probe: understanding which property your algorithm actually relies on.

What is the binary search alternative?

An alternative approach binary-searches on the value range [matrix[0][0], matrix[n-1][n-1]]. For a candidate value mid, count how many elements in the matrix are less than or equal to mid by walking from the bottom-left corner. If the count is less than K, search higher; otherwise search lower.

JAVA
package com.bank.service;

public class KthSmallestBinarySearch {

    public static int kthSmallest(int[][] grid, int k) {
        int n = grid.length;
        int low = grid[0][0], high = grid[n - 1][n - 1];

        while (low < high) {
            int mid = low + (high - low) / 2;
            int count = countLessOrEqual(grid, mid, n);
            if (count < k) {
                low = mid + 1;
            } else {
                high = mid;
            }
        }
        return low;
    }

    private static int countLessOrEqual(int[][] grid, int target, int n) {
        int count = 0;
        int row = n - 1, col = 0;
        while (row >= 0 && col < n) {
            if (grid[row][col] <= target) {
                count += row + 1; // All elements above in this column
                col++;
            } else {
                row--;
            }
        }
        return count;
    }
}

How do the two approaches compare?

| Aspect | K-way Merge (Heap) | Binary Search on Value |
|---|---|---|
| Time | O(K log N) | O(N log(max - min)) |
| Space | O(N) | O(1) |
| Better when | K is small relative to N^2 | K is large or close to N^2 |
| Uses column-sorted? | No | Yes (for counting) |

What are the edge cases?

Several edge cases require attention.

  • K = 1: the answer is always matrix[0][0], the top-left element.
  • K = N^2: the answer is always matrix[N-1][N-1], the bottom-right element.
  • 1x1 matrix: the answer is the single element.
  • All elements equal: any K gives the same value.
JAVA
package com.bank.core;

public class KthSmallestEdgeCases {
    public static void main(String[] args) {
        int[][] grid = {{100, 200}, {300, 400}};
        System.out.println("K=1: " + KthSmallestMatrixService.kthSmallest(grid, 1)); // 100
        System.out.println("K=4: " + KthSmallestMatrixService.kthSmallest(grid, 4)); // 400
    }
}
TEXT
K=1: 100
K=4: 400

What is the time and space complexity?

For the heap approach: the heap holds at most N elements (one per row), so K pops cost O(K log N) time. Space is O(N). For the binary search approach: each counting pass takes O(N) time, and we do O(log(max - min)) passes, giving O(N log(max - min)) time with O(1) extra space.

What should a senior engineer know?

A senior engineer should understand these deeper aspects.

  • Optimized seeding: seed only min(N, K) rows because no element below row K can be among the first K smallest.
  • Binary search correctness: the binary search converges to an actual matrix value because at each step we narrow to a range that must contain an element.
  • Young tableau: a matrix sorted by both rows and columns is called a Young tableau, and there are specialized algorithms for insertion and deletion in O(N) time.

Visual Overview

DIAGRAM
  Fee Grid (sorted rows and columns):
  ┌─────┬─────┬──────┐
  │ 100 │ 500 │  900 │  Row 0
  ├─────┼─────┼──────┤
  │ 200 │ 600 │ 1000 │  Row 1
  ├─────┼─────┼──────┤
  │ 400 │ 700 │ 1100 │  Row 2
  └─────┴─────┴──────┘

  K-way Merge (K=5):
  ┌────────────────────────────────────┐
  │  Seed: {100/R0, 200/R1, 400/R2}   │
  │  Pop 1: 100 -> push 500/R0        │
  │  Pop 2: 200 -> push 600/R1        │
  │  Pop 3: 400 -> push 700/R2        │
  │  Pop 4: 500 -> push 900/R0        │
  │  Pop 5: 600 -> ANSWER = 600       │
  └────────────────────────────────────┘

Key Takeaway

Kth Smallest Element in a Sorted Matrix is a K-way Merge problem once you notice that each row is already a sorted list. You seed a min-heap with the first element of each row, carrying the value along with its row and column so you can fetch the next element in that row. Then you pop K times, pushing the next cell to the right after each pop. The value of the Kth pop is the Kth smallest in the whole matrix.

The important point for interviewers is that only the row-sorted property is required for this approach to be correct. The column-sorted property is a nice bonus the problem provides, but the heap merge does not depend on it. The heap holds at most N candidates, so K pops cost O(K log N) time with O(N) space.

At the National Bank of India, Rajesh used this on a fee grid where moving right or down only increased the fee. The product team needed the Kth smallest fee to set a pricing tier boundary. Rather than flattening and sorting all N^2 cells, Rajesh ran a row-wise K-way merge and stopped at the Kth removal, which was significantly faster for small K.

The senior-level insight is knowing both the heap approach and the binary search alternative, and understanding when each is better: the heap excels when K is small, while binary search excels when K approaches N^2. Being able to articulate which matrix property each approach uses demonstrates deep understanding.

Remember one sentence: treat rows as sorted lists, seed a heap with column zero of each row, and the Kth pop gives the Kth smallest element.

---

Share
Use ← → arrow keys to navigate