原题地址:https://leetcode-cn.com/problems/kth-smallest-element-in-a-sorted-matrix/submissions/
题目描述:
给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第k小的元素。
请注意,它是排序后的第k小元素,而不是第k个元素。
示例:
matrix = [
[ 1, 5, 9],
[10, 11, 13],
[12, 13, 15]
],
k = 8,
返回 13。
说明:
你可以假设 k 的值永远是有效的, 1 ≤ k ≤ n2 。
解题方案:
常规的便利搜索,每次循环,找到当前最小值。思路比较直接,时间复杂度不低,没有用到二分查找。
代码:
class Solution {
public:
int kthSmallest(vector<vector<int>>& matrix, int k) {
int rowSize = matrix.size();
if (rowSize == 0){
return 0;
}
int colSize = matrix[0].size();
if (colSize == 0){
return 0;
}
int result;//储存结果
vector<int> rowPtr(rowSize, 0);//rowPtr[i]n表示的第i行的行指针,指向第i行的列下标
while (k > 0){
int tempRes = INT_MAX, minIndex;//用于记录当前最小的元素
//扫面一遍所有行指针,确定当前最小的值,并且标记他所在行
for (int row = 0; row < rowSize; ++row){
//rowPtr[row] < colSize不能出列界
if (rowPtr[row] < colSize && matrix[row][rowPtr[row]] < tempRes){
tempRes = matrix[row][rowPtr[row]];//更新当前最小值
minIndex = row;//标记最小值所在行
}
}
result = tempRes;//更新结果
rowPtr[minIndex] += 1;//当前寻找到的最小值所在的行指针后移
k -= 1;
}
return result;
}
};
最佳方案,用到了二分查找:
static int x = []() {
std::ios::sync_with_stdio(false);
cin.tie(NULL);
return 0;
}();
class Solution {
public:
int kthSmallest(vector<vector<int>>& matrix, int k) {
int n=matrix.size();
int begin=matrix[0][0],end=matrix[n-1][n-1];
while(begin<end)
{
int mid=begin+(end-begin)/2;
int pos=0;
for(int i=0;i<n;i++)
{
pos+=upper_bound(matrix[i].begin(),matrix[i].end(),mid)-matrix[i].begin();
}
if(pos<k)
begin=mid+1;
else
end=mid;
}
return end;
}
};