Problem Description:
Given a nxn matrix wherein each row and each column of elements in ascending order, find the small element of the matrix k.
Please note that it is the first k small element of a sort, but not the first k elements.
Example:
matrix = [
[ 1, 5, 9],
[10, 11, 13],
[12, 13, 15]
],
k = 8,
Return 13.
Note:
You can assume that the value of k is always valid, 1 ≤ k ≤ n2.
The basic idea:
Here we introduce a virtual array of concepts:
Our dichotomy is not based on our existing array. We just use our existing array of set left and right.
Our mid is based on standards set by our own , he is not necessarily in this array.
AC Code:
class Solution {
public:
int Count(vector<vector<int>> &m, int target) {
int count = 0;
int n = m.size();
// 利用基本已经排好序的矩阵的性质来统计数据
for (int i = 0; i < n; ++i) {
int j = n - 1;
while (j >= 0) {
if (m[j][i] <= target) {
count += j + 1;
break;
} else {
--j;
}
}
}
return count;
}
int kthSmallest(vector<vector<int>>& matrix, int k) {
int n = matrix.size(); // 这是一个方阵, 所以只要求一个维度就行
int left = matrix[0][0];
int right = matrix[n - 1][n - 1];
// 这里的二分并不是直接基于我们的数据结构
// 而是我们虚拟化了一个数组
int mid = left; // 防止left和right相等的时候,进不去循环
while (left < right) {
mid = left + (right - left) / 2; // mid不再是索引,而是实打实的元素值
int count = Count(matrix, mid); // 在数组中寻找比mid小的所有元素个数
// 夹逼法求得符合要求的元素
if (count >= k) right = mid; // 说明mid过大
else left = mid + 1;
}
return left; // 注意这里是返回left或者right而不是返回mid
}
};
Other experience:
Note Squeeze binary value is returned when the left and right, rather than the mid value.