您的位置:首页 > 其它

leetcode题解-378. Kth Smallest Element in a Sorted Matrix

2017-07-25 21:20 531 查看
上周刷完了链表部分的题目,这周开始看binary-search的,由于easy类的题目,大多数都只是最简单的二叉搜索,所以这里就不在进行写博客记录,而且很多题目都是之前数组或者哈希表的题目,已经做过了,我用了一周的时间专门用binary-search的方法做了一遍,现在开始看中等难度部分的题目。

题目:

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小的元素。由于该矩阵在数值的排列上并不是呈现单一的递增或递减,所以我们没有办法使用之前所熟悉的binary-search方法来做(按照索引进行二叉搜索),这里先总结一下常用的两种binary-search方法:

按照索引进行搜索(适用于排序数组,在一个维度上呈现某种规律的情况)

按照值进行搜索(数组并未排序,想要寻找一个特定的值)

所以在本题中我们就应该使用第二种方法,先找到数组的最大值和最小值,然后以此作为二叉搜索的左右两边,求出其中间值,然后看比该值小的有多少个,是否满足条件,如果满足条件就返回,不然就将左右边界修改为mid即可。代码入下所示:

public int kthSmallest(int[][] matrix, int k) {
int left=matrix[0][0], right = matrix[matrix.length-1][matrix[0].length-1] + 1, mid;
while(left <= right){
mid = left + (right-left)/2;
int count=0, j=matrix[0].length-1;
for(int i=0; i<matrix.length; i++){
while(j >= 0 && matrix[i][j] > mid) j--;
count += j+1;
}
if(count < k)left = mid+1;
else right = mid;
}
return left;
}


第二种方法是采用优先级队列的方式,首先定义一个三元组的类,存储行,列和钙元素值。然后将矩阵第一行的值都以三元组的形式保存到优先级队列当中,接下来出队,每出队一个元素都将该元素的下一行相同列的元素入队,这样做k次,我们就可以得到第k小的值。代码入下所示:

public int kthSmallest1(int[][] matrix, int k) {
int n = matrix.length;
PriorityQueue<Tuple> pq = new PriorityQueue<>();
for(int j = 0; j <= n-1; j++) pq.offer(new Tuple(0, j, matrix[0][j]));
for(int i = 0; i < k-1; i++) {
Tuple t = pq.poll();
if(t.x == n-1) continue;
pq.offer(new Tuple(t.x+1, t.y, matrix[t.x+1][t.y]));
}
return pq.poll().val;
}

class Tuple implements Comparable<Tuple> {
int x, y, val;
public Tuple (int x, int y, int val) {
this.x = x;
this.y = y;
this.val = val;
}

@Override
public int compareTo (Tuple that) {
return this.val - that.val;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: