当前位置: 首页 > 知识库问答 >
问题:

排序矩阵中的k个最小元素

丁豪
2023-03-14

所以我正在研究一个Leetcode问题,我的代码在某些情况下有效,但在某些情况下失败。

问题是:

给定一个nxn矩阵,其中每个行和列都按升序排序,找出矩阵中第k个最小的元素

请注意,它是排序顺序中的第k个最小元素,而不是第k个独立元素。

例子:

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

返回: 13

我的方法是使用minHeap,即使它声明数组已经排序,我仍然需要确保我已经将它从最小值排序到最大值。

这是我的代码:

class Solution {
    public int kthSmallest(int[][] matrix, int k) {
        int row = matrix.length;
        int col = matrix[0].length;
        int result = 0;

        HashMap<Integer, Integer> map = new HashMap<>();
        //populate HashMap 
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                map.put(matrix[i][j],
                        map.getOrDefault(matrix[i][j], 0) + 1);
            }
        }

        PriorityQueue<Map.Entry<Integer, Integer>> pq =
                new PriorityQueue<>((n1, n2) -> n1.getValue() - n2.getValue());

        pq.addAll(map.entrySet());

        for (int i = 0; i < k && !(pq.isEmpty()); i++) {
            result = pq.poll().getKey();
        }

        return result;
    }
}

以下是我的意见:

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

Input 2: [[1,2],[1,3]] 
k = 1 

以下是输出:

Output 1: 13
Output 2: 2

请注意,对于我的第一个输入,2d数组中第8个最小的元素是13,代码工作正常,但是对于第二个输入,代码返回2作为我的第一个最小元素,而不是返回1。

有人能帮我修复代码吗?我请求你不要实现一些花哨的速记排序技术,例如rrays.sort....这对我来说并不理想,因为我正在努力学习如何实现堆。谢谢:)

共有3个答案

赵修诚
2023-03-14
public static int kthSmallest(int[][] matrix, int k) {
    return Arrays
            .stream(matrix)
            .flatMapToInt(x -> Arrays.stream(x))
            .sorted()
            .skip(k-1)
            .findFirst()
            .getAsInt();
}
易流觞
2023-03-14

可以使用flatMapToInt方法在一个流中迭代二维数组的行:

public static void main(String[] args) {
    int[][] matrix1 = {{1, 5, 9}, {10, 11, 13}, {12, 13, 15}};
    int[][] matrix2 = {{1, 2}, {1, 3}};

    System.out.println(kthSmallest(matrix1, 8)); // 13
    System.out.println(kthSmallest(matrix2, 1)); // 1
}
public static int kthSmallest(int[][] matrix, int k) {
    return Arrays.stream(matrix)
            .flatMapToInt(Arrays::stream)
            .skip(k - 1)
            .findFirst()
            .getAsInt();
}
索锐藻
2023-03-14

为了解决这个问题,我们也可以二进制搜索(更有效一点):

public class Solution {
    public static final int kthSmallest(final int[][] matrix, final int k) {
        int lo = matrix[0][0];
        int hi = matrix[matrix.length - 1][matrix[0].length - 1] + 1;

        while (lo < hi) {
            final int mid = lo + (hi - lo) / 2;
            int count = 0;
            int col = matrix[0].length - 1;

            for (int row = 0; row < matrix.length; ++row) {
                while (col >= 0 && matrix[row][col] > mid) {
                    col--;
                }
                count += (col + 1);
            }
            if (count < k) {
                lo = mid + 1;
            } else {
                hi = mid;
            }
        }
        return lo;
    }
}
 类似资料:
  • 这是一个面试问题。 在具有排序行和列的矩阵中找到Kth最小元素。 Kth最小元素是中的一个,例如,这是否正确?

  • 我的问题是受到这个特殊的SO评论的启发,这个评论没有得到回答(我自己也面临这个问题): 我试图找到排序矩阵中第K个最小的元素: 给定一个nxn矩阵,其中每个行和列都按升序排序,返回矩阵中第k个最小的元素 请注意,它是排序顺序中的第k个最小元素,而不是第k个独立元素 输入:矩阵=[[1,5,9],[10,11,13],[12,13,15],[12,13,15],k=8 输出:13 说明:矩阵中的元素

  • 我知道以前有人问过这个问题,但这个问题是关于我的具体代码。我试图做一个psuedo-QuickSelect算法,将k与排序矩阵子区间的中点进行比较。 我一直收到一个超时错误。 以下是矩阵: 下面是我的代码: 我将元组传递给,其中包含区间的endpoint的。因此,如果我想搜索整个矩阵,我会传递和。将查看子区间,根据endpoint的行号确定中点,计算小于中点的元素数量,将其与进行比较。如果小于小于

  • 这是一个面试问题。 在排序的行(但不是排序的列)和行之间没有关系的矩阵中查找第k个最小元素。(第一行和第n行之间没有关系——我们只知道每一行都是按升序排列的) 输入示例如下: 这种情况下的结果是 因为20是这个矩阵中第五小的元素。 我首先想到将所有元素添加到minHeap中,然后轮询元素,同时每次迭代从k中减去一个,直到我们得到答案。我还考虑为O(m*n)解决方案实现快速选择,尽管这些解决方案并没

  • 我实现了c程序,可以找到矩阵的元素:行的最大元素,同时列的最小元素,或行的-min元素,同时列的最大元素。例如,我们有数据。包含以下内容的txt文件: 4 7 8 9 10 6 5 4 11 5 0 1 12 4 2 7 13- 其中4是n-矩阵大小(4x4),7和10是这些数字。 下面是代码: 问题:我想知道我的代码是不是“脏”代码?因为我总是渴望让一切变得如此困难,只要有可能让它变得容易。是否

  • 这可能是微软的面试问题。 从排序的数组中找出第k个最小的元素(忽略重复项) [编辑]:数组可能包含重复项(未指定)。 想了很多次,但仍然质疑自己:还有更好的解决方案吗? 取最大堆 时间复杂度:O(NlogK) 空间复杂度:O(K) 这些元素可能是重复的。所以,通过与以前的元素进行比较来检查是否有唯一的元素 还可以使用改进版的快速排序分区算法。但它可能会导致最坏的情况,因为数组已经排序<这里出现了两