Nth smallest element in sorted 2-D array in JavaScript

JavascriptWeb DevelopmentFront End Technology

Problem

Suppose, we have a sorted array of arrays of Numbers (sorted in increasing order) like this −

const arr = [
   [ 1, 5, 9],
   [10, 11, 13],
   [12, 13, 15]
];

We are required to write a JavaScript function that takes in in one such array as the first argument and a single Integer, num, as the second argument.

Our function is supposed to return the numth smallest element that exists in the array arr.

For example, if the input to the function is −

const arr = [
   [ 1, 5, 9],
   [10, 11, 13],
   [12, 13, 15]
];
const num = 5;

Output

Then the output should be −

const output = 11;

Output Explanation:

11 is the fifth smallest element in the matrix.

Example

The code for this will be −

 Live Demo

const arr = [
   [ 1, 5, 9],
   [10, 11, 13],
   [12, 13, 15]
];
const num = 5;
const kthSmallest = (arr = [], num = 1) => {
   let low = arr[0][0]
   let high = arr[arr.length-1][arr[0].length-1] + 1;
   while (low < high) {
      let mid = low + Math.floor((high-low)/2);
      let count = 0;
      for (let i = 0;i<arr.length;i++) {
         for (let j=0;j<arr.length;j++) {
            if (arr[i][j] <= mid) count++;
            else break;
         }
      }
   if (count < num) low = mid+1;
      else high = mid;
   }
   return low
};
console.log(kthSmallest(arr, num));

Code Explanation:

The idea here is −

When we have a regular sorted 2d array, we use a range of indexes to find our target, for example,

low = 0, high = length-1, mid = (low+high)/2

if the target is greater than the number at index mid, then we search the right portion, if it's smaller, we search the left.

However, in this 2d arr sorted array, it is impossible to find such a mid index. The intuition here is to use a range of numbers to test against our k. We know the first number is the smallest and the last number is the largest, this means our target number must be something in between. We can use those two numbers as our low and high, and set our mid to be the number in between, and check how many of the numbers in the arr are smaller than that number and adjust low and high accordingly.

When we get exactly k numbers, we know we have found our answer. The extremely tricky part here is that just by looking at how we calculate mid, a lot of times the number we are testing agaist may not even be in the arr, because in the end, the numbers we are using are just arbitrary numbers.

To explain this we need to imagine that our program is at a stage where low and high are almost going to hit each other. if we counted less numbers than expected, we will set low=mid+1, this potentially just increments our mid by 1. And by incrementing our mid 1 by 1, We can make sure the numbers are included in the arr.

Output

The output in the console will be −

11
raja
Published on 18-Mar-2021 09:01:45
Advertisements