📌  相关文章
📜  按行和按列排序的2D数组中的Kth个最小元素|套装1

📅  最后修改于: 2021-04-24 14:26:37             🧑  作者: Mango

给定一个nxn矩阵,其中每一行和每一列均以非降序排序。在给定的2D数组中找到第k个最小的元素。
例子,

Input:k = 3 and array =
        10, 20, 30, 40
        15, 25, 35, 45
        24, 29, 37, 48
        32, 33, 39, 50 
Output: 20
Explanation: The 3rd smallest element is 20 

Input:k = 7 and array =
        10, 20, 30, 40
        15, 25, 35, 45
        24, 29, 37, 48
        32, 33, 39, 50 
Output: 30

Explanation: The 7th smallest element is 30

方法:所以这个想法是找到第k个最小元素。每行和每一列进行排序。因此,可以将其视为C排序列表,并且必须将这些列表合并为一个列表,必须找出列表的第k个元素。因此,方法类似,唯一的区别是找到第k个元素时,循环结束。
算法:

  1. 这个想法是使用最小堆。创建最小堆以存储元素
  2. 从头到尾遍历第一行,并从第一行开始构建最小的元素堆。堆条目还存储行号和列号。
  3. 现在运行k次循环以在每次迭代中从堆中提取最小元素
  4. 从Min-Heap获取最小元素(或根)。
  5. 查找最小元素的行号和列号。
  6. 用同一列中的下一个元素替换root,并最小化根。
  7. 打印最后提取的元素,即第k个最小元素

执行:

C++
// kth largest element in a 2d array sorted row-wise and
// column-wise
#include
#include
using namespace std;
 
// A structure to store entry of heap. The entry contains
// value from 2D array, row and column numbers of the value
struct HeapNode {
    int val; // value to be stored
    int r; // Row number of value in 2D array
    int c; // Column number of value in 2D array
};
 
// A utility function to swap two HeapNode items.
void swap(HeapNode* x, HeapNode* y)
{
    HeapNode z = *x;
    *x = *y;
    *y = z;
}
 
// A utility function to minheapify the node harr[i] of a
// heap stored in harr[]
void minHeapify(HeapNode harr[], int i, int heap_size)
{
    int l = i * 2 + 1;
    int r = i * 2 + 2;
    int smallest = i;
    if (l < heap_size && harr[l].val < harr[i].val)
        smallest = l;
    if (r < heap_size && harr[r].val = 0) {
        minHeapify(harr, i, n);
        i--;
    }
}
 
// This function returns kth
// smallest element in a 2D array
// mat[][]
int kthSmallest(int mat[4][4], int n, int k)
{
    // k must be greater than 0 and smaller than n*n
    if (k > 0 && k < n * n)
        return INT_MAX;
 
    // Create a min heap of elements from first row of 2D
    // array
    HeapNode harr[n];
    for (int i = 0; i < n; i++)
        harr[i] = { mat[0][i], 0, i };
 
    HeapNode hr;
    for (int i = 0; i < k; i++) {
        // Get current heap root
        hr = harr[0];
 
        // Get next value from column of root's value. If
        // the value stored at root was last value in its
        // column, then assign INFINITE as next value
        int nextval = (hr.r < (n - 1)) ? mat[hr.r + 1][hr.c]
                                       : INT_MAX;
 
        // Update heap root with next value
        harr[0] = { nextval, (hr.r) + 1, hr.c };
 
        // Heapify root
        minHeapify(harr, 0, n);
    }
 
    // Return the value at last extracted root
    return hr.val;
}
 
// driver program to test above function
int main()
{
    int mat[4][4] = {
        { 10, 20, 30, 40 },
        { 15, 25, 35, 45 },
        { 25, 29, 37, 48 },
        { 32, 33, 39, 50 },
    };
    cout << "7th smallest element is "
         << kthSmallest(mat, 4, 7);
    return 0;
}


Java
// Java program for kth largest element in a 2d
// array sorted row-wise and column-wise
class GFG{
     
// A structure to store entry of heap.
// The entry contains value from 2D array,
// row and column numbers of the value
static class HeapNode
{
     
    // Value to be stored
    int val;
     
    // Row number of value in 2D array
    int r;
     
    // Column number of value in 2D array
    int c;
     
    HeapNode(int val, int r, int c)
    {
        this.val = val;
        this.c = c;
        this.r = r;
    }
}
 
// A utility function to swap two HeapNode items.
static void swap(int i, int min, HeapNode[] arr)
{
    HeapNode temp = arr[i];
    arr[i] = arr[min];
    arr[min] = temp;
}
 
// A utility function to minheapify the node
// harr[i] of a heap stored in harr[]
static void minHeapify(HeapNode harr[],
                       int i, int heap_size)
{
    int l = 2 * i + 1;
    int r = 2 * i + 2;
    int min = i;
     
    if (l < heap_size &&
        harr[l].val < harr[min].val)
    {
        min = l;
    }
    if (r < heap_size &&
        harr[r].val = 0)
    {
        minHeapify(harr, i, n);
        i--;
    }
}
 
// This function returns kth smallest
// element in a 2D array mat[][]
public static int kthSmallest(int[][] mat,
                              int n, int k)
{
     
    // k must be greater than 0 and
    // smaller than n*n
    if (k > 0 && k < n * n)
    {
        return Integer.MAX_VALUE;
    }
     
    // Create a min heap of elements
    // from first row of 2D array
    HeapNode harr[] = new HeapNode[n];
     
    for(int i = 0; i < n; i++)
    {
        harr[i] = new HeapNode(mat[0][i], 0, i);
    }
     
    HeapNode hr = new HeapNode(0, 0, 0);
     
    for(int i = 1; i <= k; i++)
    {
         
        // Get current heap root
        hr = harr[0];
         
        // Get next value from column of root's
        // value. If the value stored at root was
        // last value in its column, then assign
        // INFINITE as next value
        int nextVal = hr.r < n - 1 ?
                      mat[hr.r + 1][hr.c] :
                      Integer.MAX_VALUE;
                       
        // Update heap root with next value
        harr[0] = new HeapNode(nextVal,
                               hr.r + 1, hr.c);
                                
        // Heapify root
        minHeapify(harr, 0, n);
    }
     
    // Return the value at last extracted root
    return hr.val;
}
 
// Driver code
public static void main(String args[])
{
    int mat[][] = { { 10, 20, 30, 40 },
                    { 15, 25, 35, 45 },
                    { 25, 29, 37, 48 },
                    { 32, 33, 39, 50 } };
                     
    int res = kthSmallest(mat, 4, 7);
     
    System.out.print("7th smallest element is "+ res);
}
}
 
// This code is contributed by nikhil kumar sharma


Python3
# Program for kth largest element in a 2d array
# sorted row-wise and column-wise
from sys import maxsize
 
# A structure to store an entry of heap.
# The entry contains a value from 2D array,
# row and column numbers of the value
class HeapNode:
    def __init__(self, val, r, c):
        self.val = val # value to be stored
        self.r = r # Row number of value in 2D array
        self.c = c # Column number of value in 2D array
 
# A utility function to minheapify the node harr[i]
# of a heap stored in harr[]
def minHeapify(harr, i, heap_size):
    l = i * 2 + 1
    r = i * 2 + 2
    smallest = i
    if l < heap_size and harr[l].val < harr[i].val:
        smallest = l
    if r < heap_size and harr[r].val = 0:
        minHeapify(harr, i, n)
        i -= 1
 
# This function returns kth smallest element
# in a 2D array mat[][]
def kthSmallest(mat, n, k):
 
    # k must be greater than 0 and smaller than n*n
    if k  n * n:
        return maxsize
 
    # Create a min heap of elements from
    # first row of 2D array
    harr = [0] * n
    for i in range(n):
        harr[i] = HeapNode(mat[0][i], 0, i)
    buildHeap(harr, n)
 
    hr = HeapNode(0, 0, 0)
    for i in range(k):
 
        # Get current heap root
        hr = harr[0]
 
        # Get next value from column of root's value.
        # If the value stored at root was last value
        # in its column, then assign INFINITE as next value
        nextval = mat[hr.r + 1][hr.c]
                       if (hr.r < n - 1) else maxsize
 
        # Update heap root with next value
        harr[0] = HeapNode(nextval, hr.r + 1, hr.c)
 
        # Heapify root
        minHeapify(harr, 0, n)
 
    # Return the value at last extracted root
    return hr.val
 
# Driver Code
if __name__ == "__main__":
    mat = [[10, 20, 30, 40],
        [15, 25, 35, 45],
        [25, 29, 37, 48],
        [32, 33, 39, 50]]
    print("7th smallest element is",
            kthSmallest(mat, 4, 7))
 
# This code is contributed by
# sanjeev2552


C#
// C# program for kth largest element in a 2d
// array sorted row-wise and column-wise
using System;
 
class GFG{
     
// A structure to store entry of heap.
// The entry contains value from 2D array,
// row and column numbers of the value
class HeapNode
{
     
    // Value to be stored
    public int val;
     
    // Row number of value in 2D array
    public int r;
     
    // Column number of value in 2D array
    public int c;
     
    public HeapNode(int val, int r, int c)
    {
        this.val = val;
        this.c = c;
        this.r = r;
    }
}
 
// A utility function to swap two
// HeapNode items.
static void swap(int i, int min,
                 HeapNode[] arr)
{
    HeapNode temp = arr[i];
    arr[i] = arr[min];
    arr[min] = temp;
}
 
// A utility function to minheapify the node
// harr[i] of a heap stored in harr[]
static void minHeapify(HeapNode []harr,
                       int i, int heap_size)
{
    int l = 2 * i + 1;
    int r = 2 * i + 2;
    int min = i;
     
    if (l < heap_size &&
        harr[l].val < harr[i].val)
    {
        min = l;
    }
    if (r < heap_size &&
        harr[r].val = 0)
    {
        minHeapify(harr, i, n);
        i--;
    }
}
 
// This function returns kth smallest
// element in a 2D array [,]mat
public static int kthSmallest(int[,] mat,
                              int n, int k)
{
     
    // k must be greater than 0 and
    // smaller than n*n
    if (k  n * n)
    {
        return int.MaxValue;
    }
     
    // Create a min heap of elements
    // from first row of 2D array
    HeapNode []harr = new HeapNode[n];
     
    for(int i = 0; i < n; i++)
    {
        harr[i] = new HeapNode(mat[0, i], 0, i);
    }
    buildHeap(harr, n);
     
    HeapNode hr = new HeapNode(0, 0, 0);
     
    for(int i = 1; i < k; i++)
    {
         
        // Get current heap root
        hr = harr[0];
         
        // Get next value from column of root's
        // value. If the value stored at root was
        // last value in its column, then assign
        // INFINITE as next value
        int nextVal = hr.r < n - 1 ?
                      mat[hr.r + 1, hr.c] :
                      int.MaxValue;
                       
        // Update heap root with next value
        harr[0] = new HeapNode(nextVal,
                               hr.r + 1, hr.c);
                                
        // Heapify root
        minHeapify(harr, 0, n);
    }
     
    // Return the value at last
    // extracted root
    return hr.val;
}
 
// Driver code
public static void Main(String []args)
{
    int [,]mat = { { 10, 20, 30, 40 },
                   { 15, 25, 35, 45 },
                   { 25, 29, 37, 48 },
                   { 32, 33, 39, 50 } };
                     
    int res = kthSmallest(mat, 4, 7);
     
    Console.Write("7th smallest element is " + res);
}
}
 
// This code is contributed by Amit Katiyar


输出:

7th smallest element is 30

复杂度分析:

  • 时间复杂度:上述解决方案涉及以下步骤。
    1. 建立耗时O(n)的最小堆
    2. 堆k次,这需要O(k Logn)时间。
  • 空间复杂度: O(R),其中R是一行的长度,因为Min-Heap一次存储一行。