有序数组中第K小的数字

Screenshot from 2020-07-02 05-29-42

思路

首先 想到的就是暴力算法,将二维数组拆成一维数组,排序(或者直接放进优先队列)最后竟然过了。。。Screenshot from 2020-07-02 06-15-38

因为矩阵在行列方向上都是升序排列的,在有序数组中搜索一个数字常用二分法,所以可以考虑变种的二分法。

二维数组从左下向右上搜索,每次搜索检查一下当前搜遍历到数字范围有没有超过k。

image-20200702085025147

代码

暴力:

import java.util.Arrays;

class Solution {
    public int kthSmallest(int[][] matrix, int k) {
        int n = matrix.length;
        int[] nums = new int[n*n];
        int index = 0;
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++){
                nums[index++] = matrix[i][j];
            }
        }

        Arrays.sort(nums);
        return nums[k-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;
    }

    /**
     * 检查小于等于mid的数字数量是否大于等于k
     * num表示小于等于mid的数字数量
     * @param matrix
     * @param mid
     * @param k
     * @param n
     * @return
     */
    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;
                j++;
            }
            else{
                i--;
            }
        }
        return num >= k;
    }
}
posted @ 2020-07-02 08:52  zjy4fun  阅读(268)  评论(0编辑  收藏  举报