leetcode中等378有序矩阵中第 K 小的元素
Posted qq_40707462
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode中等378有序矩阵中第 K 小的元素相关的知识,希望对你有一定的参考价值。
给你一个 n x n 矩阵 matrix ,其中每行和每列元素均按升序排序,找到矩阵中第 k 小的元素。
请注意,它是 排序后 的第 k 小元素,而不是第 k 个 不同 的元素。
你必须找到一个内存复杂度优于 O(n2) 的解决方案。
示例 1:
输入:matrix = [[1,5,9],[10,11,13],[12,13,15]], k = 8
输出:13
解释:矩阵中的元素为 [1,5,9,10,11,12,13,13,15],第 8 小元素是 13
思路1:优先队列
class Solution
public int kthSmallest(int[][] matrix, int k)
PriorityQueue<Integer>pq=new PriorityQueue<>((n1,n2)->(n2-n1));//大顶堆
for(int[]a:matrix)
for(int b:a)
pq.offer(b);
if(pq.size()>k) pq.poll();
return pq.peek();
思路2:归并排序
类似 23、合并K个升序链表【困难】,合并 n 行
注意优先队列里要记录当前数的坐标
时间复杂度:O(klogn),归并 k 次,每次堆中插入和弹出的操作时间复杂度均为 logn。
空间复杂度:O(n),堆的大小始终为 n。
class Solution
public int kthSmallest(int[][] matrix, int k)
PriorityQueue<int[]>pq=new PriorityQueue<>
((int[]n1,int[]n2)->(n1[0]-n2[0]));//小顶堆
int n=matrix.length;
for(int i=0;i<n;i++) pq.offer(new int[]matrix[i][0],i,0);
for(int i=0;i<k-1;i++)//弹出当前最小的一个,弹出k-1次
int[]cur=pq.poll();
if(cur[2]!=n-1)
pq.offer(new int[]matrix[cur[1]][cur[2]+1],cur[1],cur[2]+1);
return pq.poll()[0];
思路3:二分
整个二维数组中 matrix[0][0] 为最小值,matrix[n−1][n−1] 为最大值,将其分别记作 l 和 r。
任取一个数 mid 满足 l≤mid≤r,那么矩阵中不大于 mid 的数,肯定全部分布在矩阵的左上角。
例如下图,取 mid=8:
- 初始位置在 matrix[n−1][0](即左下角);
- 设当前位置为 matrix[i][j]。若 matrix[i][j]≤mid,则将当前所在列的不大于 mid 的数的数量(即 i+1)累加到答案中,并向右移动,否则向上移动;不断移动直到走出格子为止。
- 每次对于「猜测」的答案 mid,计算矩阵中有多少数不大于 mid :
如果数量不少于 k,那么说明最终答案 x 不大于 mid;
如果数量少于 k,那么说明最终答案 x 大于 mid。
时间复杂度:O(nlog(r−l)),二分查找进行次数为O(log(r−l)),每次操作时间复杂度为 O(n)。
空间复杂度:O(1)
class Solution
public int kthSmallest(int[][] matrix, int k)
int n = matrix.length;
int left = matrix[0][0];
int right = matrix[n - 1][n - 1];
while (left < right)
int mid = left + ((right - left) >> 1);
if (check(matrix, mid, k, n))
right = mid;
else
left = mid + 1;
return left;
public boolean check(int[][] matrix, int mid, int k, int n)
int i = n - 1;
int j = 0;
int num = 0;
while (i >= 0 && j < n)
if (matrix[i][j] <= mid)
num += i + 1;//这一列[0,i]共i+1个数
j++;//右移
else
i--;//上移
return num >= k;
以上是关于leetcode中等378有序矩阵中第 K 小的元素的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 378. 有序矩阵中第K小的元素 | Python
leetcode.矩阵.378有序矩阵中第K小的元素-Java