有序矩阵中第K小的元素(LeetCode第378题)java实现

一、题目描述

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

 示例: 


matrix = [
   [ 1,  5,  9],
   [10, 11, 13],
   [12, 13, 15]
],
k = 8,

返回 13。


 说明: 
你可以假设 k 的值永远是有效的, 1 ≤ k ≤ n2 。 

二、解题思路

方法一、先从小到大排序,再找第k个元素。(解析略)

方法二、用含k个节点的小顶堆来遍历二维数组的所有元素。(解析略)

方法三、用二分法来求。(详解)

直接求解矩阵中的第8小元素很难,我们可以用二分法设定一个值mid,查看mid值是否是矩阵第8小元素。
具体思路为:
1.首先设置mid的初值为矩阵matrix,最后一个数和第一个数的平均值。
2.统计矩阵中每一行小于mid值的个数之和。若该值小于8,记录当前mid,L = mid + 1,并更新mid;若该值大于8,R = mid - 1。
3.重复上述搜索,直至L和R不满足L <= R,此时的mid值即为所求。
三、java代码(方法三)

class Solution {

    public static boolean f_CompareMidAndK(int[][] matrix, int g, int n, int k){
        int count = 0;
        for (int i = 0; i < n; i++) {
            int L = 0;
            int R = n - 1;
            int ans = 0;
            while (L <= R){
                int mid = L + ((R - L) >> 2);
                if(matrix[i][mid] < g){
                    ans = mid + 1;
                    L = mid + 1;
                }else {
                    R = mid - 1;
                }
            }
            count += ans;
        }
        return count < k;
    }

    public static int kthSmallest(int[][] matrix, int k) {
        int res = 0;
        int n = matrix.length;
        int L = matrix[0][0];
        int R = matrix[n - 1][n - 1];
        while (L <= R) {
            //没有用 (L+R)/2 是这样会有溢出
            int mid = L + ((R - L) >> 2);
            if (f_CompareMidAndK(matrix, mid, n, k)) {
                //比较该二维数组中小于mid的元素个数 是否 小于 k 个
                res = mid;
                L = mid + 1;
            } else {
                R = mid - 1;
            }
        }
        return res;
    }
}

 

你可能感兴趣的:(LeetCode刷题)