您的位置:首页 > 其它

【leetcode】378. Kth Smallest Element in a Sorted Matrix

2016-08-06 13:21 417 查看
一、题目描述

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.

题目解读:给出一个矩阵,该矩阵每一行每一列都是从小到大排好序的。找出矩阵中第 k 大的数

方法一:将矩阵中每个元素放入一个数组中,然后对数组进行排序,然后取出第k大的数

c++代码1:使用sort 函数(112ms)

class Solution {
public:
int kthSmallest(vector<vector<int>>& matrix, int k) {
int row=matrix.size(); //行
int col=matrix[0].size();  //列
vector<int> number;
for(int i=0; i<row; i++){
for(int j=0; j<col; j++){
number.push_back(matrix[i][j]);
}//for
}//for
sort(number.begin(), number.end());
return number[k-1];
}
};


c++代码2:使用nth_element函数(52ms)

class Solution {
public:
int kthSmallest(vector<vector<int>>& matrix, int k) {
int row=matrix.size(); //行
int col=matrix[0].size();  //列
int* number = new int[row*col];
for(int i=0; i<row; i++){
for(int j=0; j<col; j++){
number[i*col+j]=matrix[i][j];
}//for
}//for
nth_element(number, number+k-1, number+(row*col));
return number[k-1];
}
};


注意nth_element 函数有个坑,第 k 大的元素是从0开始,因此nth_element里面是 number+k-1 而不是number+k,return返回的也是位置在 k-1 的元素。

方法二:利用矩阵每一行每一列都有序的性质,设置一个最小堆(用priority_queue实现),从左上角的matrix[0][0] 开始,每从堆中取出一个元素就计数count,当count=k时,取出的这个节点的值就是所求,否则当前节点的右边节点和下边节点放入堆中。

此处采用(val, i, j)的形式存储每一个节点,也就是说不仅要存储节点的值,还要存储节点的位置。比如一个节点的位置为i, j,那么该节点的右边节点的位置为 i, j+1, 下边节点是 i+1, j。这里还要注意的一点就是要判断i+1或者j+1有没有超界,并且要判断节点是否已加入过队列了。只有位置没越界并且从来没有加入过队列的节点才能被加入。判断是否加入过队列可以通过设置一个二维数组visited[i][j]来判断位置i,j 的节点是否加入过,没加入过值为0,加入过值为1。

c++代码(132ms)

struct Node{
int val;  //值
int x;  //横坐标
int y;  //竖坐标
Node(int val, int x, int y):
val(val), x(x), y(y) {}
bool operator < (const Node & x)const {
return val>x.val;
}
};

class Solution {
public:
int kthSmallest(vector<vector<int>>& matrix, int k) {
int row=matrix.size();  //行数
int col=matrix[0].size(); //列数
priority_queue<Node> p;
int count=0;
p.push(Node(matrix[0][0], 0, 0));
int i,j;
//动态分配一个二维数组来存储已经入队的节点的位置
int **visited = new int* [row];  //开辟行
for(int i=0; i<row; i++){
visited[i] = new int [col];  //开辟列
} //for
for(int i=0; i<row; i++){
for(int j=0; j<col; j++){
visited[i][j]=0;
}
}
visited[0][0]=1;
int result;

while(count<k && !p.empty()){
count++;
if(count==k){
result=p.top().val;
break;
}
else{
i=p.top().x;
j=p.top().y;
p.pop();
if((i+1)<row && visited[i+1][j]==0){  //行数
p.push(Node(matrix[i+1][j], i+1, j));
visited[i+1][j]=1;
}
if((j+1)<col && visited[i][j+1]==0){//列数
p.push(Node(matrix[i][j+1], i, j+1));
visited[i][j+1]=1;
}

}//else
}//while
return result;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: