1,题目要求
Given a n x n matrix where each of the rows and columns are sorted in ascending order, find the kth smallest element in the matrix.
Note that it is the kth smallest element in the sorted order, not the kth distinct element.
Example:
matrix = [
[ 1, 5, 9],
[10, 11, 13],
[12, 13, 15]
],
k = 8,
return 13.
Note:
You may assume k is always valid, 1 ≤ k ≤ n2.
给定n×n矩阵,其中每个行和列按升序排序,找到矩阵中的第k个最小元素。
请注意,它是排序顺序中的第k个最小元素,而不是第k个不同元素。
2,题目思路
对于这道题,要求找到一个矩阵中第k小的数字。
题目中,给定的这个矩阵是n*n且是有序的,因此,为了找到第k小的数字,我们可以将这个矩阵作为一个一维数组来进行操作。
而一般来说,我们实现一个查找方法,使用二分查找是最常用的。想要在这个二维矩阵中实现一维的二分,就要对元素的位置在对应的一维数组里的位置做一个“映射”才行。
这里,使用到了upper_bound方法:
upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
3,代码实现
static auto speedup = [](){
ios::sync_with_stdio(false);
cin.tie(nullptr);
return nullptr;
}();
class Solution {
public:
int kthSmallest(vector<vector<int>>& matrix, int k) {
//二维数组一维化
int N = matrix.size();
if(N == 0)
return 0;
int left = matrix[0][0];
int right = matrix[N-1][N-1];
int mid = 0;
while(left < right){
int acutalPos = 0;
mid = left + (right - left)/2;
for(auto &n : matrix){
int currPos = upper_bound(n.begin(), n.end(), mid) - n.begin();
acutalPos += currPos;
}
if(acutalPos < k)
left = mid + 1;
else
right = mid;
}
return left;
}
};