题目描述
知识点
【分类思想】+【堆】
结果
实现
码前思考
- 首先,我看到这道题目中的
Kth Smallest
就想起了可能要使用堆来解决问题,因为堆的常见用法就是Kth
的问题; - 然后我再想到了之前在⭐【分类思想+堆】LeetCode 373. Find K Pairs with Smallest Sums中用到的分类思想;
- 综上,我得出了自己的实现代码。
代码实现
struct node{
int x;
int y;
int val;
node(){}
node(int _x,int _y,int _val):x(_x),y(_y),val(_val){}
friend bool operator < (node a,node b){
return a.val > b.val;
}
};
//对于这种kth的问题使用堆来解决~
class Solution {
public:
int kthSmallest(vector<vector<int>>& matrix, int k) {
int size = matrix.size();
//设置一个是否访问的数组
vector<vector<bool> > vis(size,vector<bool>(size,false));
//优先队列
priority_queue<node> q;
//初始化优先队列q
q.push(node(0,0,matrix[0][0]));
//设置为已经访问
vis[0][0] = true;
int res;
while(k--){
node root = q.top();
int x = root.x;
int y = root.y;
res = root.val;
//如果有右边,并且右边,没有被访问
if(y+1<=size-1 && vis[x][y+1] == false){
q.push(node(x,y+1,matrix[x][y+1]));
vis[x][y+1] = true;
}
//如果有下面,并且下面没有被访问
if(x+1<=size-1 && vis[x+1][y] == false){
q.push(node(x+1,y,matrix[x+1][y]));
vis[x+1][y] = true;
}
//弹出
q.pop();
}
return res;
}
};
码后反思
- 其实我的代码还是没有体现“堆”在处理
Kth
问题的优势😔 - 堆的主要好处就是在处理
Kth
问题时,只保持堆的大小为K
,这样就能极大地降低时间复杂度。 下面的代码虽然是遍历整个数组矩阵,但是由于堆的大小为K
,所以能够实现比其他遍历更优的时间复杂度:class Solution { public: int kthSmallest(vector<vector<int>>& matrix, int k) { priority_queue<int> pq; for (int i = 0; i < matrix.size(); ++i) { for (int j = 0; j < matrix[0].size(); ++j) { pq.push(matrix[i][j]); if (pq.size() > k) pq.pop(); } } return pq.top(); } };
- 这道题据说还能用二分来解决。后面再看吧。
- 注意不能重复放某一个元素,所以要设置一个
bool vis[maxn]
数组!