378. Kth Smallest Element in a Sorted Matrix - Medium

本文探讨了在排序矩阵中寻找第k小元素的有效算法,包括使用最小堆和二分搜索两种方法。通过实例说明了如何利用这些算法解决具体问题,提供了代码实现,并分析了时间复杂度。

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

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.

 

M1: heap,建立一个min heap,先把最小元素{0, 0}放进heap。用cnt计数,如果++cnt == k时,找到第k小的元素,返回。

因为数组每行每列都是有序的,每次循环时把heap中的最小值poll出来,如果是第一行,把该元素右边的元素加入heap,然后把该元素下方的元素加入heap。用一个参数cnt计数,当++cnt = k里,返回matrix对应坐标的值。

time: O(klogk), space: O(k) 

class Solution {
    public int kthSmallest(int[][] matrix, int k) {
        PriorityQueue<int[]> minHeap = new PriorityQueue<>(k, (a, b) -> matrix[a[0]][a[1]] - matrix[b[0]][b[1]]);
        int cnt = 0;
        minHeap.add(new int[] {0, 0});
        while(true) {
            int[] pair = minHeap.poll();
            if(++cnt == k)
                return matrix[pair[0]][pair[1]];
            
            if(pair[0] == 0 && pair[1] + 1 < matrix[0].length)
                minHeap.add(new int[] {pair[0], pair[1] + 1});
                
            if(pair[0] + 1 < matrix.length)
                minHeap.add(new int[] {pair[0] + 1, pair[1]});                
        }
    }
}

另一种写法:

从最小的元素开始,依次访问最小元素的neighbor(当neighbor下标不越界且没被访问过,入队,并标记为已访问),循环k次。最后最小堆的堆顶元素就是第k小元素的坐标

time: O(klogk), space: O(k + n^2)

class Solution {
    public int kthSmallest(int[][] matrix, int k) {
        boolean[][] visited = new boolean[matrix.length][matrix[0].length];
        PriorityQueue<int[]> minHeap = new PriorityQueue<>((a, b) -> matrix[a[0]][a[1]] - matrix[b[0]][b[1]]);
        minHeap.offer(new int[] {0, 0});
        
        for(int i = 0; i < k - 1; i++) {
            int[] idx = minHeap.poll();
            int row = idx[0], col = idx[1];
            visited[row][col] = true;
            
            if(row + 1 < matrix.length && !visited[row+1][col]) {
                minHeap.offer(new int[] {row + 1, col});
                visited[row+1][col] = true;
            }
            if(col + 1 < matrix[0].length && !visited[row][col+1]) {
                minHeap.offer(new int[] {row, col + 1});
                visited[row][col+1] = true;
            }
        }
        
        int[] res = minHeap.peek();
        return matrix[res[0]][res[1]];
    }
}

 

M2: binary search,原理同 287. find the duplicate number https://www.cnblogs.com/fatttcat/p/9986854.html

time: O(NlogN), space: O(1)

 

转载于:https://www.cnblogs.com/fatttcat/p/9992882.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值