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

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

题目描述

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

示例:

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

返回 13。

说明:

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

思路

思路1:二分法

使用两个哨兵分别记录最大值和最小值(可以取到第k个值的区间),然后计算中间值的大小,根据这个中间值计算第k个值在二分区间中的位置,或者是大于多少个矩阵中的值,若比k大则属于前半区间,若小于等于k则处于后半区间,等于由于可能中间值不是矩阵中的值所以不能直接返回

代码

代码1

class Solution {
    public int kthSmallest(int[][] matrix, int k) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0){
            throw new RuntimeException("matrix is empty!");
        }
        int rowSize = matrix.length;
        int colSize = matrix[0].length;
        if (k > colSize * rowSize){
            throw new RuntimeException("matrix is less than k!");
        }
        
        int left = matrix[0][0];
        int right = matrix[matrix.length - 1][matrix[0].length - 1];
        int count = -1;
        
        while (left < right){
            int mid = (left + right) / 2;
            count = getCount(matrix, mid, rowSize, colSize);
            if (count < k){
                left = mid + 1;
            }else{
                right = mid;
            }
        }
        return right;
    }
    
    private int getCount(int[][] matrix,int mid,int rowSize,int colSize){
        int rowIndex = rowSize - 1;
        int colIndex = 0;
        int count = 0;
        
        while (rowIndex >= 0 && colIndex < colSize){
            if (matrix[rowIndex][colIndex] <= mid){
                count += rowIndex + 1;
                colIndex ++;
            }else{
                rowIndex --;
            }
        }
        return count;
    }
}

复杂度分析

时间复杂度

$O(nlogn * log (max -min))$log(max - min)是因为有中间值逼近的过程

空间复杂度

$O(1)$


文章作者: 小风雷
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 小风雷 !
评论
 上一篇
Leetcode:347. 前 K 个高频元素 Leetcode:347. 前 K 个高频元素
Leetcode:347. 前 K 个高频元素题目描述给定一个非空的整数数组,返回其中出现频率前 k 高的元素。 示例 1:输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2:输入: nums
2020-04-01
下一篇 
Leetcode:295. 数据流的中位数 Leetcode:295. 数据流的中位数
Leetcode:295. 数据流的中位数题目描述中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。 例如, [2,3,4] 的中位数是 3 [2,3] 的中位数是 (2 + 3) / 2 = 2.5 设计一
2020-03-30
  目录