我指的是leetcode问题:Kth Smallest Element in a Sorted Matrix
这个问题有两个众所周知的解决方案 . 使用Heap / PriorityQueue和其他人使用二进制搜索 . 二进制搜索解决方案是这样的(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;
}
}
虽然我理解这是如何工作的,但我很难搞清楚一个问题 . 我们怎样才能确定返回的 lo
总是在矩阵中?
由于搜索空间是数组的 min
和 max
值,因此 mid
不必是数组中的值 . 但是,返回的 lo
始终是 .
为什么会这样?
1 回答
为了论证,我们可以将
count
的计算移动到一个单独的函数,如下所示:此谓词将与指定的操作完全相同 . 这里,循环不变量是,范围
[lo, hi]
始终包含kth
最小数量的2D数组 .换句话说,
lo <= solution <= hi
现在,当循环终止时,显然
lo >= hi
合并这两个属性,得到
lo = solution = hi
,因为solution
是数组的成员,可以说,lo
总是在循环终止后的数组中,并且会正确地指向kth
最小元素 .