有序矩阵中第 K 小的元素

本文探讨了如何在升序排列的矩阵中寻找第k小的元素。介绍了四种不同的解决方案,包括使用优先队列(堆排序)的两种方法,二分查找策略以及直接展开排序。其中,堆排序方法的时间复杂度为O(Nlogk),空间复杂度为O(K)。文章通过示例详细解释了每种思路,并提供了C++实现的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、描述

给你一个 n x n 矩阵 matrix ,其中每行和每列元素均按升序排序,找到矩阵中第 k 小的元素。
请注意,它是 排序后 的第 k 小元素,而不是第 k 个 不同 的元素。

示例 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
示例 2:

输入:matrix = [[-5]], k = 1
输出:-5

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/kth-smallest-element-in-a-sorted-matrix
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2、关键字

有序,矩阵,第k小

3、思路

思路1:优先队列:堆排序。
第k小,数组,直接搞成大根堆,逐个的添加,添加完整个数组,大根堆的top就是所求,又因为是有序矩阵,所以有一个break的操作,和上一个题的那个break,提前终止内部循环一样。

  • 思路2:优先队列,堆排序,合并k个有序链表解法一样,搞成小根堆。时间复杂度:O(klogn),比我写的这个要快一点。我写的是O(Nlogk),N更大。

  • 思路3、二分查找,

  • 思路4、直接展开排序之后根据下标找到

4、notes

看下思路中对应的题和题解
1、堆的插入和弹出操作,时间复杂度:log(n),n是堆大小,元素个数。
2、c++默认大根堆。
3、这个if— else if结构,一个是直接分成两部分,从第二部分中再分,上一个是从一个全集中分出一部分,再根据条件分出另外一部分,然后再从剩下的再分出其他的一部分。

if(){
}
else{
	if(){
	}
	else{
	}
}

// 和这种:
if(){
}
else if(){
}
else if(){
}
else if(){
}


5、复杂度

时间:O(Nlogk),N是遍历整个矩阵,logK是堆的插入和弹出操作。
空间:O(K)堆的大小

5、code

class Solution {
public:
    int kthSmallest(vector<vector<int>>& matrix, int k) {
        //priority_queue<int,vector<int>,less<int>> heap;
        priority_queue<int> heap;  // 第k小,从左往右,搞成大根堆,堆内存的是小的数,
        int n = matrix.size();
        int m = matrix[0].size();
        for(auto & tem : matrix){
            for(auto & num : tem){
                if(heap.size() < k){
                    heap.push(num);
                }
                else{
                    if(heap.top() > num){
                        heap.pop();
                        heap.push(num);
                    }
                    else{
                        break;
                    }
                }
            }
        }
        return heap.top();
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值