LeetCode.378. 有序矩阵中第K小的元素

在这里插入图片描述
思路:
1.使用最小堆
我的做法就是使用最小堆来存放那些可能的最小值,一个值为当前最小值,那么下一个最小值会是它的右边和下边的那个值,因此要把这两个都放进最小堆里面去,为了防止存放重复的数字还搞了个布尔数组。

class Solution {
    public int kthSmallest(int[][] matrix, int k) {
        if(matrix == null || matrix[0].length < 1){
            return 0;
        }
        int m = matrix.length;
        int n = matrix[0].length;
        class Node{
            int val;
            int i;
            int j;
            Node(int i,int j,int val){
                this.val = val;
                this.i = i;
                this.j = j;
            }
        }
        boolean[][] visited = new boolean[m][n];
        visited[0][0] = true;
        PriorityQueue<Node> pq = new PriorityQueue<>(new Comparator<Node>(){
            public int compare(Node a,Node b){
                return a.val - b.val;
            }
        });
        
        Node tmp = new Node(0,0,matrix[0][0]);
        pq.add(tmp);
        while(k > 0){
            tmp = pq.poll();
            int r = tmp.i;
            int c = tmp.j;
            if(r + 1 < m && c + 1 < n){
                if(!visited[r][c+1]){
                    pq.add(new Node(r,c+1,matrix[r][c+1]));
                    visited[r][c+1] = true;
                }             
                if(!visited[r+1][c]){
                    pq.add(new Node(r+1,c,matrix[r+1][c]));
                    visited[r+1][c] = true;
                }
            }else if(r + 1 < m){
                if(!visited[r+1][c]){
                    pq.add(new Node(r+1,c,matrix[r+1][c]));
                    visited[r+1][c] = true;
                }
            }else if(c + 1 < n){
                if(!visited[r][c+1]){
                    pq.add(new Node(r,c+1,matrix[r][c+1]));
                    visited[r][c+1] = true;
                }  
            }
            k--;
        }
        return tmp.val;
    }
}

看了别人的做法以后,觉得自己真是野路子,别人是这样做的,相当于n路合并的那道题,把n行的开头都存入堆里,如果某行的第一个是最小值,就将它的下一个元素存储在最小堆里。直到找到第K个最小值

class Solution {
    public int kthSmallest(int[][] matrix, int k) {
        if(matrix == null || matrix[0].length < 1){
            return 0;
        }
        int n = matrix[0].length;
        class Node{
            int val;
            int i;
            int j;
            Node(int i,int j,int val){
                this.val = val;
                this.i = i;
                this.j = j;
            }
        }
        PriorityQueue<Node> pq = new PriorityQueue<>(new Comparator<Node>(){
            public int compare(Node a,Node b){
                return a.val - b.val;
            }
        });
        for(int t = 0;t < n;t++){
            pq.add(new Node(t,0,matrix[t][0]));
        }

        while(k > 1){
            Node tmp = pq.poll();
            k--;
            if(tmp.j == n-1){
                continue;
            }
            pq.add(new Node(tmp.i,tmp.j+1,matrix[tmp.i][tmp.j+1]));
        }
        return pq.poll().val;
    }
}

2.使用二分查找法
这篇博客讲解的较详细

class Solution {
    public int kthSmallest(int[][] matrix, int k) {
        if(matrix == null || matrix[0].length < 1){
            return 0;
        }
        int n = matrix.length;
        int left = matrix[0][0];
        int right = matrix[n-1][n-1];
        while(left < right){
            int mid = left + right >> 1;
            int count = findSmaller(matrix,mid);
            if(count >= k){
                right = mid;;
            }else{
                left = mid+1; 
            }
        }
        return right;
    }
    public int findSmaller(int[][] matrix,int target){
        int row = matrix.length - 1;
        int col = 0;
        int count = 0;
        while(row >= 0 && col < matrix.length){
            if(matrix[row][col] <= target){
                col++;
                count += row + 1;
            }else{
                row--;
            }
        }
        return count;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值