给定一个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个元素时,循环结束。
算法:
- 这个想法是使用最小堆。创建最小堆以存储元素
- 从头到尾遍历第一行,并从第一行开始构建最小的元素堆。堆条目还存储行号和列号。
- 现在运行k次循环以在每次迭代中从堆中提取最小元素
- 从Min-Heap获取最小元素(或根)。
- 查找最小元素的行号和列号。
- 用同一列中的下一个元素替换root,并最小化根。
- 打印最后提取的元素,即第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
复杂度分析:
- 时间复杂度:上述解决方案涉及以下步骤。
- 建立耗时O(n)的最小堆
- 堆k次,这需要O(k Logn)时间。
- 空间复杂度: O(R),其中R是一行的长度,因为Min-Heap一次存储一行。