ℹ️ Select 'Choose Exercise', or randomize 'Next Random Exercise' in selected language.

Choose Exercise:
Timer 00:00
WPM --
Score --
Acc --
Correct chars --

K-th Smallest Element in a Sorted Matrix

R

Goal -- WPM

Ready
Exercise Algorithm Area
1################################################################################
2# K-th Smallest Element in a Sorted Matrix
3#
4# This function finds the k-th smallest element in an n x n matrix where each row
5# and column is sorted in ascending order. It employs a binary search approach on
6# the possible values of the elements to efficiently find the k-th smallest.
7################################################################################
8
9# Helper function to count elements less than or equal to a given value 'x'.
10# This is the core of the binary search strategy.
11count_less_equal <- function(matrix, x, n) {
12count <- 0
13# Start from the bottom-left corner of the matrix.
14# This is an efficient starting point because if matrix[i, j] <= x,
15# then all elements to its left in the same row (matrix[i, 1...j]) are also <= x.
16# If matrix[i, j] > x, then all elements below it in the same column (matrix[i...n, j]) are also > x.
17row <- n
18col <- 1
19
20while (row >= 1 && col <= n) {
21if (matrix[row, col] <= x) {
22# If the current element is less than or equal to x,
23# it means all elements in this row from col to the end (n) are also <= x.
24# So, we add (n - col + 1) to the count.
25count <- count + (n - col + 1)
26# Move to the next row to check for more elements <= x.
27row <- row - 1
28} else {
29# If the current element is greater than x,
30# it means this element and all elements below it in this column are > x.
31# So, we must move to the left in the same row to find smaller elements.
32col <- col + 1
33}
34}
35return(count)
36}
37
38# Main function to find the k-th smallest element.
39find_kth_smallest <- function(matrix, k) {
40# Get the dimensions of the matrix (assuming it's n x n).
41n <- nrow(matrix)
42
43# Edge case: Empty matrix.
44if (n == 0) {
45stop("Matrix cannot be empty.")
46}
47
48# Edge case: k is out of bounds.
49if (k < 1 || k > n * n) {
50stop(paste("k must be between 1 and", n * n, "inclusive."))
51}
52
53# Define the search space for the k-th smallest element.
54# The smallest possible value is the top-left element.
55# The largest possible value is the bottom-right element.
56low <- matrix[1, 1]
57high <- matrix[n, n]
58ans <- high # Initialize answer to a safe upper bound
59
60# Perform binary search on the range of possible values.
61while (low <= high) {
62# Calculate the middle value in the current search range.
63mid <- floor((low + high) / 2)
64
65# Count how many elements in the matrix are less than or equal to 'mid'.
66count <- count_less_equal(matrix, mid, n)
67
68# If the count of elements <= mid is at least k:
69# This means 'mid' could be our k-th smallest element, or the k-th smallest
70# element is even smaller than 'mid'. We record 'mid' as a potential answer
71# and try to find a smaller value by searching in the lower half.
72if (count >= k) {
73ans <- mid # 'mid' is a candidate for the k-th smallest
74high <- mid - 1 # Search in the lower half
75} else {
76# If the count of elements <= mid is less than k:
77# This means 'mid' is too small. The k-th smallest element must be
78# larger than 'mid'. We search in the upper half.
79low <- mid + 1 # Search in the upper half
80}
81}
82
83# After the binary search, 'ans' will hold the k-th smallest element.
84# The invariant is that 'ans' always stores the smallest value found so far
85# for which count_less_equal(matrix, ans, n) >= k.
86return(ans)
87}
88
89# Example Usage:
90# matrix1 <- matrix(c(1, 5, 9, 10, 11, 13, 15, 16, 19), nrow = 3, byrow = TRUE)
91# k1 <- 8
92# print(paste("The", k1, "-th smallest element is:", find_kth_smallest(matrix1, k1))) # Expected: 16
93
94# matrix2 <- matrix(c(-5), nrow = 1, byrow = TRUE)
95# k2 <- 1
96# print(paste("The", k2, "-th smallest element is:", find_kth_smallest(matrix2, k2))) # Expected: -5
97
98# matrix3 <- matrix(c(1, 2, 3, 4, 5, 6, 7, 8, 9), nrow = 3, byrow = TRUE)
99# k3 <- 5
100# print(paste("The", k3, "-th smallest element is:", find_kth_smallest(matrix3, k3))) # Expected: 5
Algorithm description viewbox

K-th Smallest Element in a Sorted Matrix

Algorithm description:

This R code finds the k-th smallest element in a matrix where both rows and columns are sorted in ascending order. Instead of flattening and sorting the entire matrix, which would be O(N^2 log N^2), it uses a binary search approach on the range of possible element values. This significantly improves efficiency, making it suitable for large matrices. This technique is valuable in competitive programming and scenarios requiring efficient retrieval of order statistics from structured data.

Algorithm explanation:

The `find_kth_smallest` function efficiently finds the k-th smallest element in a sorted matrix. It leverages binary search on the range of possible values, from the smallest element (`matrix[1, 1]`) to the largest (`matrix[n, n]`). For each `mid` value in the binary search, it calls `count_less_equal` to determine how many elements in the matrix are less than or equal to `mid`. The `count_less_equal` helper function uses a clever two-pointer approach starting from the bottom-left corner of the matrix. If `matrix[row, col] <= mid`, it means all elements to the right in that row are also less than or equal to `mid`, so we add `n - col + 1` to the count and move up a row. Otherwise, if `matrix[row, col] > mid`, we move left in the same row to find smaller elements. If `count >= k`, it implies `mid` is a potential answer, and we try smaller values by searching in the lower half (`high = mid - 1`). If `count < k`, `mid` is too small, and we search in the upper half (`low = mid + 1`). The loop invariant is that `ans` always holds the smallest value encountered so far for which `count_less_equal` returns at least `k`. The time complexity is O(N log(MaxVal - MinVal)), where N is the dimension of the matrix and MaxVal/MinVal are the maximum/minimum values in the matrix. The space complexity is O(1) (excluding input storage).

Pseudocode:

FUNCTION find_kth_smallest(matrix, k):
  n = number of rows in matrix

  IF n == 0 THEN
    THROW ERROR "Matrix is empty"
  END IF
  IF k < 1 OR k > n*n THEN
    THROW ERROR "k is out of bounds"
  END IF

  low = matrix[1, 1]
  high = matrix[n, n]
  ans = high

  WHILE low <= high:
    mid = floor((low + high) / 2)
    count = count_less_equal(matrix, mid, n)

    IF count >= k THEN
      ans = mid
      high = mid - 1
    ELSE
      low = mid + 1
    END IF
  END WHILE

  RETURN ans

FUNCTION count_less_equal(matrix, x, n):
  count = 0
  row = n
  col = 1

  WHILE row >= 1 AND col <= n:
    IF matrix[row, col] <= x THEN
      count = count + (n - col + 1)
      row = row - 1
    ELSE
      col = col + 1
    END IF
  END WHILE
  RETURN count