LeetCode-378. Kth Smallest Element in a Sorted Matrix
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.
解题思路:首先此题可以利用priority_queue队列来求解,即建立一个最大堆,堆大小为k.遍历完元素后堆根为第k小的元素。
class Solution
{
int kthSmallest(vector<vector<int>>& matrix, int k)
{
priority_queue<int> que;
for (auto it=matrix.begin();it!=matrix.end();++it)
for (auto newit = (*it).begin(); newit != (*it).end(); newit++)
{
if (que.size() < k)que.push(*newit);
else if (que.top() > *newit)
{
que.pop();
que.push(*newit);
}
}
return que.top();
}
};
另外可以用二分查找来进行求解,这里用到了upper_bound。介绍一下upper_bound和lower_bound。 两个函数的用法类似,用于在一个左闭右开的有序区间里进行二分查找,需要查找的值由第三个参数给出。 对于upper_bound来说,返回的是被查序列中第一个大于查找值的指针,也就是返回指向被查值>查找值的最小指针,lower_bound则是返回的是被查序列中第一个大于等于查找值的指针,也就是返回指向被查值>=查找值的最小指针。
这两个函数还分别有一个重载函数,可以接受第四个参数。如果第四个参数传入greater<Type>()
,其中Type改成对应类型,那么upper_bound则返回指向被查值<查找值的最小指针,lower_bound则返回指向被查值<=查找值的最小指针。 简单来说,如果你用上述两个函数三个参数的那种形式,记得那个左闭右开的区间要为非递减的顺序,如果你给第四个参数传入greater<Type>()
,则区间为非递增的顺序。
class Solution
{
public:
int kthSmallest(vector<vector<int>>& matrix, int k)
{
int n = matrix.size();
int le = matrix[0][0], ri = matrix[n - 1][n - 1];
int mid = 0;
while (le < ri)
{
mid = le + (ri - le) / 2;
int num = 0;
for (int i = 0; i < n; i++)
{
int pos = upper_bound(matrix[i].begin(), matrix[i].end(), mid) - matrix[i].begin();
num += pos;
}
if (num < k)le = mid + 1;
else ri = mid;
}
return le;
}
};