1

I'm referring to the leetcode question: Kth Smallest Element in a Sorted Matrix

There are two well-known solutions to the problem. One using Heap/PriorityQueue and other is using Binary Search. The Binary Search solution goes like this (top post):

public class Solution {
public int kthSmallest(int[][] matrix, int k) {
    int lo = matrix[0][0], hi = matrix[matrix.length - 1][matrix[0].length - 1] + 1;//[lo, hi)
    while(lo < hi) {
        int mid = lo + (hi - lo) / 2;
        int count = 0,  j = matrix[0].length - 1;
        for(int i = 0; i < matrix.length; i++) {
            while(j >= 0 && matrix[i][j] > mid) j--;
            count += (j + 1);
        }
        if(count < k) lo = mid + 1;
        else hi = mid;
    }
    return lo;
}
}

While I understand how this works, I have trouble figuring out one issue. How can we be sure that the returned lo is always in the matrix?

Since the search space is min and max value of the array, the mid need NOT be a value that is in the array. However, the returned lo always is.

Why is this happening?

Snehasis Ghosh
  • 739
  • 6
  • 10

2 Answers2

0

For the sake of argument, we can move the calculation of count to a separate function like the following:

bool valid(int mid, int[][] matrix, int k) {
    int count = 0, m = matrix.length;
    for (int i = 0; i < m; i++) {
        int j = 0;
        while (j < m && matrix[i][j] <= mid) j++;
        count += j;
    }
    return (count < k);
}

This predicate will do exactly same as your specified operation. Here, the loop invariant is that, the range [lo, hi] always contains the kth smallest number of the 2D array.

In other words, lo <= solution <= hi

Now, when the loop terminates, it is evident that lo >= hi

Merging those two properties, we get, lo = solution = hi, since solution is a member of array, it can be said that, lo is always in the array after loop termination and will rightly point to the kth smallest element.

SALEH
  • 1,552
  • 1
  • 13
  • 22
  • This is where I'm confused. Why is `solution` always in the array? If my range is [0,1,2,3,4,5,.....n-2,n-1,n] of [[0,1],[n-1,n]] matrix, the `mid` can be any number from [0,n] in between loops. However when low>=hi and the loop terminates, why does the low and mid have to be between [0,1,n-1,n]. – Snehasis Ghosh Mar 21 '18 at 05:33
  • @ Snehasis Ghosh The solution variable is defined as the result of this problem – James LT Sep 23 '18 at 22:47
0

Because We are finding the lower_bound using binary search and there cannot be any number smaller than the number(lo) in the array which could be the kth smallest element.