Given an n x n matrix, where every row and column is sorted in non-decreasing order. Find the kth smallest element in the given 2D array.
Example,
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
BRUTE METHOD:
Intuition:
- We create a PriorityQueue<Integer> to store all the elements of the matrix.
- Then we traverse through the the priority queue and if k elements are popped out, then we return the element.
- As by default min heap is implemented by PriorityQueue.
Implementation:
C++
#include <iostream>
#include <queue>
using namespace std;
int kthSmallest( int arr[][4], int n, int k)
{
priority_queue< int , vector< int >, greater< int > > pq;
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < n; j++) {
pq.push(arr[i][j]);
}
}
int c = 0;
while (!pq.empty()) {
int temp = pq.top();
pq.pop();
c++;
if (c == k)
return temp;
}
return -1;
}
int main()
{
int mat[4][4] = { { 10, 20, 30, 40 },
{ 15, 25, 35, 45 },
{ 25, 29, 37, 48 },
{ 32, 33, 39, 50 } };
int res = kthSmallest(mat, 4, 7);
cout << "7th smallest element is " << res << endl;
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
public static int kthSmallest( int [][] arr, int n, int k)
{
PriorityQueue<Integer> pq = new PriorityQueue<>();
for ( int i = 0 ; i < n; i++) {
for ( int j = 0 ; j < n; j++) {
pq.add(arr[i][j]);
}
}
int c = 0 ;
while (!pq.isEmpty()) {
int temp = pq.poll();
c++;
if (c == k)
return temp;
}
return - 1 ;
}
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);
}
}
|
Python3
import heapq
def kthSmallest(arr, n, k):
pq = []
for i in range (n):
for j in range (n):
heapq.heappush(pq, arr[i][j])
c = 0
while pq:
temp = heapq.heappop(pq)
c + = 1
if c = = k:
return temp
return - 1
if __name__ = = "__main__" :
mat = [
[ 10 , 20 , 30 , 40 ],
[ 15 , 25 , 35 , 45 ],
[ 25 , 29 , 37 , 48 ],
[ 32 , 33 , 39 , 50 ]
]
res = kthSmallest(mat, 4 , 7 )
print ( "7th smallest element is" , res)
|
C#
using System;
using System.Collections.Generic;
class Program {
static int KthSmallest( int [, ] arr, int n, int k)
{
PriorityQueue< int > pq = new PriorityQueue< int >();
for ( int i = 0; i < n; i++) {
for ( int j = 0; j < n; j++) {
pq.Push(arr[i, j]);
}
}
int c = 0;
while (!pq.IsEmpty()) {
int temp = pq.Pop();
c++;
if (c == k)
return temp;
}
return -1;
}
static void Main()
{
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.WriteLine( "7th smallest element is " + res);
}
}
class PriorityQueue<T> where T : IComparable<T> {
private List<T> heap;
public PriorityQueue() { heap = new List<T>(); }
public void Push(T value)
{
heap.Add(value);
int currentIndex = heap.Count - 1;
while (currentIndex > 0) {
int parentIndex = (currentIndex - 1) / 2;
if (heap[currentIndex].CompareTo(
heap[parentIndex])
>= 0)
break ;
Swap(currentIndex, parentIndex);
currentIndex = parentIndex;
}
}
public T Pop()
{
int lastIndex = heap.Count - 1;
T minValue = heap[0];
heap[0] = heap[lastIndex];
heap.RemoveAt(lastIndex);
int currentIndex = 0;
lastIndex--;
while ( true ) {
int leftChildIndex = currentIndex * 2 + 1;
int rightChildIndex = currentIndex * 2 + 2;
if (leftChildIndex > lastIndex)
break ;
int smallerChildIndex = leftChildIndex;
if (rightChildIndex <= lastIndex
&& heap[rightChildIndex].CompareTo(
heap[leftChildIndex])
< 0) {
smallerChildIndex = rightChildIndex;
}
if (heap[currentIndex].CompareTo(
heap[smallerChildIndex])
<= 0)
break ;
Swap(currentIndex, smallerChildIndex);
currentIndex = smallerChildIndex;
}
return minValue;
}
public bool IsEmpty() { return heap.Count == 0; }
private void Swap( int i, int j)
{
T temp = heap[i];
heap[i] = heap[j];
heap[j] = temp;
}
}
|
Javascript
function kthSmallest(arr, n, k) {
const pq = new PriorityQueue();
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
pq.enqueue(arr[i][j]);
}
}
let c = 0;
let result = -1;
while (!pq.isEmpty()) {
const temp = pq.dequeue();
c++;
if (c === k) {
result = temp;
break ;
}
}
return result;
}
class PriorityQueue {
constructor() {
this .heap = [];
}
enqueue(val) {
this .heap.push(val);
this .bubbleUp();
}
dequeue() {
if ( this .isEmpty()) return undefined;
if ( this .heap.length === 1) return this .heap.pop();
const min = this .heap[0];
const end = this .heap.pop();
this .heap[0] = end;
this .sinkDown();
return min;
}
isEmpty() {
return this .heap.length === 0;
}
bubbleUp() {
let idx = this .heap.length - 1;
const element = this .heap[idx];
while (idx > 0) {
const parentIdx = Math.floor((idx - 1) / 2);
const parent = this .heap[parentIdx];
if (element >= parent) break ;
this .heap[parentIdx] = element;
this .heap[idx] = parent;
idx = parentIdx;
}
}
sinkDown() {
let idx = 0;
const length = this .heap.length;
const element = this .heap[0];
while ( true ) {
const leftChildIdx = 2 * idx + 1;
const rightChildIdx = 2 * idx + 2;
let leftChild, rightChild;
let swap = null ;
if (leftChildIdx < length) {
leftChild = this .heap[leftChildIdx];
if (leftChild < element) {
swap = leftChildIdx;
}
}
if (rightChildIdx < length) {
rightChild = this .heap[rightChildIdx];
if (
(swap === null && rightChild < element) ||
(swap !== null && rightChild < leftChild)
) {
swap = rightChildIdx;
}
}
if (swap === null ) break ;
this .heap[idx] = this .heap[swap];
this .heap[swap] = element;
idx = swap;
}
}
}
const mat = [
[10, 20, 30, 40],
[15, 25, 35, 45],
[25, 29, 37, 48],
[32, 33, 39, 50],
];
const k = 7;
const res = kthSmallest(mat, 4, k);
console.log(`The ${k}th smallest element is ${res}`);
|
Output
7th smallest element is 30
Time Complexity: O(N^2* log(N^2)); since insertion in priority queue takes log N time and we have inserted N^2 elements.
Space Complexity: O(N^2)
Approach: So the idea is to find the kth minimum element. Each row and each column is sorted. So it can be thought as C sorted lists and the lists have to be merged into a single list, the kth element of the list has to be found out. So the approach is similar, the only difference is when the kth element is found the loop ends.
Algorithm:
- The idea is to use min heap. Create a Min-Heap to store the elements
- Traverse the first row from start to end and build a min heap of elements from first row. A heap entry also stores row number and column number.
- Now Run a loop k times to extract min element from heap in each iteration
- Get minimum element (or root) from Min-Heap.
- Find row number and column number of the minimum element.
- Replace root with the next element from same column and min-heapify the root.
- Print the last extracted element, which is the kth minimum element
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
struct HeapNode {
int val;
int r;
int c;
};
void minHeapify(HeapNode harr[], int i, int heap_size)
{
int l = i * 2 + 1;
int r = i * 2 + 2;
if (l < heap_size&& r<heap_size && harr[l].val < harr[i].val && harr[r].val < harr[i].val){
HeapNode temp=harr[r];
harr[r]=harr[i];
harr[i]=harr[l];
harr[l]=temp;
minHeapify(harr ,l,heap_size);
minHeapify(harr ,r,heap_size);
}
if (l < heap_size && harr[l].val < harr[i].val){
HeapNode temp=harr[i];
harr[i]=harr[l];
harr[l]=temp;
minHeapify(harr ,l,heap_size);
}
}
int kthSmallest( int mat[4][4], int n, int k)
{
if (k < 0 || k >= n * n)
return INT_MAX;
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++) {
hr = harr[0];
int nextval = (hr.r < (n - 1)) ? mat[hr.r + 1][hr.c]: INT_MAX;
harr[0] = { nextval, (hr.r) + 1, hr.c };
minHeapify(harr, 0, n);
}
return hr.val;
}
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
import java.io.*;
public class GFG{
static class HeapNode
{
int val;
int r;
int c;
HeapNode( int val, int r, int c)
{
this .val = val;
this .c = c;
this .r = r;
}
}
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&& r<heap_size && harr[l].val < harr[i].val && harr[r].val < harr[i].val){
HeapNode temp=harr[r];
harr[r]=harr[i];
harr[i]=harr[l];
harr[l]=temp;
minHeapify(harr ,l,heap_size);
minHeapify(harr ,r,heap_size);
}
if (l < heap_size && harr[l].val < harr[i].val){
HeapNode temp=harr[i];
harr[i]=harr[l];
harr[l]=temp;
minHeapify(harr ,l,heap_size);
}
}
public static int kthSmallest( int [][] mat, int n, int k)
{
if (k < 0 && k >= n * n)
return Integer.MAX_VALUE;
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++)
{
hr = harr[ 0 ];
int nextVal = hr.r < n - 1 ?
mat[hr.r + 1 ][hr.c] :
Integer.MAX_VALUE;
harr[ 0 ] = new HeapNode(nextVal,
hr.r + 1 , hr.c);
minHeapify(harr, 0 , n);
}
return hr.val;
}
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);
}
}
|
Python3
from sys import maxsize
class HeapNode:
def __init__( self , val, r, c):
self .val = val
self .r = r
self .c = c
def minHeapify(harr, i, heap_size):
l = i * 2 + 1
r = i * 2 + 2
if (l < heap_size and r<heap_size and harr[l].val < harr[i].val and harr[r].val < harr[i].val):
temp = HeapNode( 0 , 0 , 0 )
temp = harr[r]
harr[r] = harr[i]
harr[i] = harr[l]
harr[l] = temp
minHeapify(harr ,l,heap_size)
minHeapify(harr ,r,heap_size)
if (l < heap_size and harr[l].val < harr[i].val):
temp = HeapNode( 0 , 0 , 0 )
temp = harr[i]
harr[i] = harr[l]
harr[l] = temp
minHeapify(harr ,l,heap_size)
def kthSmallest(mat, n, k):
if k < 0 or k > n * n:
return maxsize
harr = [ 0 ] * n
for i in range (n):
harr[i] = HeapNode(mat[ 0 ][i], 0 , i)
hr = HeapNode( 0 , 0 , 0 )
for i in range (k):
hr = harr[ 0 ]
nextval = mat[hr.r + 1 ][hr.c] if (hr.r < n - 1 ) else maxsize
harr[ 0 ] = HeapNode(nextval, hr.r + 1 , hr.c)
minHeapify(harr, 0 , n)
return hr.val
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 ))
|
C#
using System;
class GFG{
class HeapNode
{
public int val;
public int r;
public int c;
public HeapNode( int val, int r, int c)
{
this .val = val;
this .c = c;
this .r = r;
}
}
static void minHeapify(HeapNode []harr, int i, int heap_size){
int l = 2 * i + 1;
int r = 2 * i + 2;
if (l < heap_size && r < heap_size && harr[l].val < harr[i].val && harr[r].val < harr[i].val){
HeapNode temp = new HeapNode(0, 0, 0);
temp=harr[r];
harr[r]=harr[i];
harr[i]=harr[l];
harr[l]=temp;
minHeapify(harr ,l,heap_size);
minHeapify(harr ,r,heap_size);
}
if (l < heap_size && harr[l].val < harr[i].val){
HeapNode temp = new HeapNode(0, 0, 0);
temp = harr[i];
harr[i]=harr[l];
harr[l]=temp;
minHeapify(harr ,l,heap_size);
}
}
public static int kthSmallest( int [,] mat, int n, int k)
{
if (k < 0 || k > n * n)
{
return int .MaxValue;
}
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 = 0; i < k; i++)
{
hr = harr[0];
int nextVal = hr.r < n - 1 ?
mat[hr.r + 1, hr.c] :
int .MaxValue;
harr[0] = new HeapNode(nextVal, hr.r + 1, hr.c);
minHeapify(harr, 0, n);
}
return hr.val;
}
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);
}
}
|
Javascript
<script>
class HeapNode
{
constructor(val,r,c)
{
this .val = val;
this .c = c;
this .r = r;
}
}
function minHeapify(harr,i,heap_size)
{
let l = 2 * i + 1;
let r = 2 * i + 2;
let min = i;
if (l < heap_size&& r<heap_size && harr[l].val < harr[i].val && harr[r].val < harr[i].val){
let temp=harr[r];
harr[r]=harr[i];
harr[i]=harr[l];
harr[l]=temp;
minHeapify(harr ,l,heap_size);
minHeapify(harr ,r,heap_size);
}
if (l < heap_size && harr[l].val < harr[i].val){
let temp=harr[i];
harr[i]=harr[l];
harr[l]=temp;
minHeapify(harr ,l,heap_size);
}
}
function kthSmallest(mat,n,k)
{
if (k < 0 && k >= n * n)
return Number.MAX_VALUE;
let harr = new Array(n);
for (let i = 0; i < n; i++)
{
harr[i] = new HeapNode(mat[0][i], 0, i);
}
let hr = new HeapNode(0, 0, 0);
for (let i = 1; i <= k; i++)
{
hr = harr[0];
let nextVal = hr.r < n - 1 ?
mat[hr.r + 1][hr.c] :
Number.MAX_VALUE;
harr[0] = new HeapNode(nextVal,
hr.r + 1, hr.c);
minHeapify(harr, 0, n);
}
return hr.val;
}
let mat=[[ 10, 20, 30, 40 ],
[ 15, 25, 35, 45 ],
[ 25, 29, 37, 48 ],
[ 32, 33, 39, 50 ]];
let res = kthSmallest(mat, 4, 7);
document.write( "7th smallest element is " + res);
</script>
|
Output
7th smallest element is 30
The codes above are contributed by RISHABH CHAUHAN.
Complexity Analysis:
- Time Complexity: The above solution involves following steps.
- Building a min-heap which takes O(n) time
- Heapify k times which takes O(k Logn) time.
- Auxiliary Space: O(R), where R is the length of a row, as the Min-Heap stores one row at a time.
The above code can be optimized to build a heap of size k when k is smaller than n. In that case, the kth smallest element must be in first k rows and k columns.
We will soon be publishing more efficient algorithms for finding the kth smallest element.
This article is compiled by Ravi Gupta. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above
Using inbuilt priority_queue :
By using a comparator, we can carry out custom comparison in priority_queue. We will use priority_queue<pair<int,int>> for this.
Implementation :
C++
#include<bits/stdc++.h>
using namespace std;
int kthSmallest( int mat[4][4], int n, int k)
{
auto cmp = [&](pair< int , int > a,pair< int , int > b){
return mat[a.first][a.second] > mat[b.first][b.second];
};
priority_queue<pair< int , int >,vector<pair< int , int >>, decltype (cmp)> pq(cmp);
for ( int i=0; i<n; i++){
pq.push({i,0});
}
for ( int i=1; i<k; i++){
auto p = pq.top();
pq.pop();
if (p.second+1 < n) pq.push({p.first,p.second + 1});
}
return mat[pq.top().first][pq.top().second];
}
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
import java.util.*;
public class GFG {
static class pair {
int first, second;
pair( int f, int s)
{
first = f;
second = s;
}
}
static int kthSmallest( int mat[][], int n, int k)
{
PriorityQueue<pair> pq
= new PriorityQueue<>((pair a, pair b) -> {
return mat[a.first][a.second]
- mat[b.first][b.second];
});
for ( int i = 0 ; i < n; i++) {
pq.add( new pair(i, 0 ));
}
for ( int i = 1 ; i < k; i++) {
pair p = pq.peek();
pq.remove();
if (p.second + 1 < n)
pq.add( new pair(p.first, p.second + 1 ));
}
return mat[pq.peek().first][pq.peek().second];
}
public static void main(String[] args)
{
int mat[][] = {
{ 10 , 20 , 30 , 40 },
{ 15 , 25 , 35 , 45 },
{ 25 , 29 , 37 , 48 },
{ 32 , 33 , 39 , 50 },
};
System.out.println( "7th smallest element is "
+ kthSmallest(mat, 4 , 7 ));
}
}
|
Python3
import heapq
def kthSmallest(mat, n, k):
cmp = lambda a,b: mat[a[ 0 ]][a[ 1 ]] - mat[b[ 0 ]][b[ 1 ]]
heap = [(mat[i][ 0 ], i, 0 ) for i in range (n)]
heapq.heapify(heap)
for i in range (k - 1 ):
val, row, col = heapq.heappop(heap)
if col < n - 1 :
heapq.heappush(heap, (mat[row][col + 1 ], row, col + 1 ))
return heap[ 0 ][ 0 ]
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 ))
|
C#
using System;
using System.Collections.Generic;
public class GFG
{
static int kthSmallest( int [,] mat, int n, int k)
{
Comparison<( int , int )> cmp = (a, b) => mat[a.Item1, a.Item2].CompareTo(mat[b.Item1, b.Item2]);
var pq = new PriorityQueue<( int , int )>(cmp);
for ( int i = 0; i < n; i++)
{
pq.Enqueue((i, 0));
}
for ( int i = 1; i < k; i++)
{
var p = pq.Peek();
pq.Dequeue();
if (p.Item2 + 1 < n) pq.Enqueue((p.Item1, p.Item2 + 1));
}
return mat[pq.Peek().Item1, pq.Peek().Item2];
}
public static void Main()
{
int [,] mat = {
{ 10, 20, 30, 40 },
{ 15, 25, 35, 45 },
{ 25, 29, 37, 48 },
{ 32, 33, 39, 50 },
};
Console.WriteLine( "7th smallest element is " + kthSmallest(mat, 4, 7));
}
}
public class PriorityQueue<T>
{
private Comparison<T> _comparer;
private List<T> _heap = new List<T>();
public PriorityQueue() { _comparer = Comparer<T>.Default.Compare; }
public PriorityQueue(Comparison<T> comparer) { _comparer = comparer; }
public void Enqueue(T item)
{
_heap.Add(item);
int i = _heap.Count - 1;
while (i > 0)
{
int parent = (i - 1) / 2;
if (_comparer(_heap[parent], _heap[i]) <= 0)
break ;
T tmp = _heap[parent];
_heap[parent] = _heap[i];
_heap[i] = tmp;
i = parent;
}
}
public T Dequeue()
{
int last = _heap.Count - 1;
T frontItem = _heap[0];
_heap[0] = _heap[last];
_heap.RemoveAt(last);
--last;
int i = 0;
while ( true )
{
int child = i * 2 + 1;
if (child > last)
break ;
if (child + 1 <= last && _comparer(_heap[child], _heap[child + 1]) > 0)
child++;
if (_comparer(_heap[i], _heap[child]) > 0)
{
T tmp = _heap[i];
_heap[i] = _heap[child];
_heap[child] = tmp;
}
else
break ;
i = child;
}
return frontItem;
}
public T Peek() { return _heap[0]; }
public int Count { get { return _heap.Count; } }
public bool Any() { return _heap.Count > 0; }
}
|
Javascript
function kthSmallest(mat, n, k) {
const cmp = (a, b) => mat[a[0]][a[1]] < mat[b[0]][b[1]];
let heap = [];
for (let i = 0; i < n; i++) {
heap.push([i, 0]);
}
for (let i = 1; i < k; i++) {
let [r, c] = heap[0];
if (c + 1 < n) {
heap[0] = [r, c+1];
} else {
heap[0] = heap[heap.length - 1];
heap.pop();
}
let j = 0;
while (2*j+1 < heap.length) {
let left = 2*j+1;
let right = 2*j+2 < heap.length ? 2*j+2 : left;
let minChild = cmp(heap[left], heap[right]) ? left : right;
if (cmp(heap[minChild], heap[j])) {
[heap[j], heap[minChild]] = [heap[minChild], heap[j]];
j = minChild;
} else {
break ;
}
}
}
let [r, c] = heap[0];
return mat[r];
}
let mat = [ [10, 20, 30, 40],
[15, 25, 35, 45],
[25, 29, 37, 48],
[32, 33, 39, 50],
];
console.log( "7th smallest element is " + kthSmallest(mat, 4, 7));
|
Output
7th smallest element is 30
Time Complexity: O(n log n)
Auxiliary Space: O(n)
Using Binary Search over the Range:
This approach uses binary search to iterate over possible solutions. We know that
- answer >= mat[0][0]
- answer <= mat[N-1][N-1]
So we do a binary search on this range and in each iteration determine the no of elements greater than or equal to our current middle element. The elements greater than or equal to current element can be found in O( n logn ) time using binary search.
C++
#include <bits/stdc++.h>
using namespace std;
int getElementsGreaterThanOrEqual( int num, int n, int mat[4][4]) {
int ans = 0;
for ( int i = 0; i < n; i++) {
if (mat[i][0] > num) {
return ans;
}
if (mat[i][n - 1] <= num) {
ans += n;
continue ;
}
int greaterThan = 0;
for ( int jump = n / 2; jump >= 1; jump /= 2) {
while (greaterThan + jump < n &&
mat[i][greaterThan + jump] <= num) {
greaterThan += jump;
}
}
ans += greaterThan + 1;
}
return ans;
}
int kthSmallest( int mat[4][4], int n, int k) {
int l = mat[0][0], r = mat[n - 1][n - 1];
while (l <= r) {
int mid = l + (r - l) / 2;
int greaterThanOrEqualMid = getElementsGreaterThanOrEqual(mid, n, mat);
if (greaterThanOrEqualMid >= k)
r = mid - 1;
else
l = mid + 1;
}
return l;
}
int main() {
int n = 4;
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
import java.io.*;
class GFG {
static int getElementsGreaterThanOrEqual( int num, int n, int mat[][])
{
int ans = 0 ;
for ( int i = 0 ; i < n; i++)
{
if (mat[i][ 0 ] > num) {
return ans;
}
if (mat[i][n - 1 ] <= num) {
ans += n;
continue ;
}
int greaterThan = 0 ;
for ( int jump = n / 2 ; jump >= 1 ; jump /= 2 ) {
while (greaterThan + jump < n &&
mat[i][greaterThan + jump] <= num) {
greaterThan += jump;
}
}
ans += greaterThan + 1 ;
}
return ans;
}
static int kthSmallest( int mat[][], int n, int k)
{
int l = mat[ 0 ][ 0 ], r = mat[n - 1 ][n - 1 ];
while (l <= r) {
int mid = l + (r - l) / 2 ;
int greaterThanOrEqualMid = getElementsGreaterThanOrEqual(mid, n, mat);
if (greaterThanOrEqualMid >= k)
r = mid - 1 ;
else
l = mid + 1 ;
}
return l;
}
public static void main(String args[]) {
int mat[][] = {
{ 10 , 20 , 30 , 40 },
{ 15 , 25 , 35 , 45 },
{ 25 , 29 , 37 , 48 },
{ 32 , 33 , 39 , 50 },
};
System.out.println( "7th smallest element is " + kthSmallest(mat, 4 , 7 ));
}
}
|
Python3
def getElementsGreaterThanOrEqual(num,n,mat):
ans = 0
for i in range (n):
if (mat[i][ 0 ] > num):
return ans
if (mat[i][n - 1 ] < = num):
ans + = n
continue
greaterThan = 0
jump = n / / 2
while (jump > = 1 ):
while (greaterThan + jump < n and mat[i][greaterThan + jump] < = num):
greaterThan + = jump
jump / / = 2
ans + = greaterThan + 1
return ans
def kthSmallest(mat, n, k):
l,r = mat[ 0 ][ 0 ],mat[n - 1 ][n - 1 ]
while (l < = r):
mid = l + (r - l) / / 2
greaterThanOrEqualMid = getElementsGreaterThanOrEqual(mid, n, mat)
if (greaterThanOrEqualMid > = k):
r = mid - 1
else :
l = mid + 1
return l
n = 4
mat = [[ 10 , 20 , 30 , 40 ],[ 15 , 25 , 35 , 45 ],[ 25 , 29 , 37 , 48 ],[ 32 , 33 , 39 , 50 ]]
print (f "7th smallest element is {kthSmallest(mat, 4, 7)}" )
|
C#
using System;
public class GFG
{
static int getElementsGreaterThanOrEqual( int num, int n, int [,]mat)
{
int ans = 0;
for ( int i = 0; i < n; i++)
{
if (mat[i,0] > num) {
return ans;
}
if (mat[i,n - 1] <= num) {
ans += n;
continue ;
}
int greaterThan = 0;
for ( int jump = n / 2; jump >= 1; jump /= 2) {
while (greaterThan + jump < n &&
mat[i,greaterThan + jump] <= num) {
greaterThan += jump;
}
}
ans += greaterThan + 1;
}
return ans;
}
static int kthSmallest( int [,]mat, int n, int k)
{
int l = mat[0,0], r = mat[n - 1,n - 1];
while (l <= r) {
int mid = l + (r - l) / 2;
int greaterThanOrEqualMid = getElementsGreaterThanOrEqual(mid, n, mat);
if (greaterThanOrEqualMid >= k)
r = mid - 1;
else
l = mid + 1;
}
return l;
}
public static void Main(String []args) {
int [,]mat = {
{ 10, 20, 30, 40 },
{ 15, 25, 35, 45 },
{ 25, 29, 37, 48 },
{ 32, 33, 39, 50 },
};
Console.WriteLine( "7th smallest element is " + kthSmallest(mat, 4, 7));
}
}
|
Javascript
<script>
function getElementsGreaterThanOrEqual(num,n,mat)
{
let ans = 0
for (let i = 0; i < n; i++) {
if (mat[i][0] > num) {
return ans;
}
if (mat[i][n - 1] <= num) {
ans += n;
continue ;
}
let greaterThan = 0;
for (let jump = n / 2; jump >= 1; jump /= 2) {
while (greaterThan + jump < n &&
mat[i][greaterThan + jump] <= num) {
greaterThan += jump;
}
}
ans += greaterThan + 1;
}
return ans;
}
function kthSmallest(mat,n,k)
{
let l = mat[0][0], r = mat[n - 1][n - 1];
while (l <= r) {
let mid = l + parseInt((r - l) / 2, 10);
let greaterThanOrEqualMid =
getElementsGreaterThanOrEqual(mid, n, mat);
if (greaterThanOrEqualMid >= k)
r = mid - 1;
else
l = mid + 1;
}
return l;
}
let n = 4;
let mat = [
[10, 20, 30, 40],
[15, 25, 35, 45],
[25, 29, 37, 48],
[32, 33, 39, 50],
];
document.write( "7th smallest element is " +
kthSmallest(mat, 4, 7));
</script>
|
Output
7th smallest element is 30
Complexity Analysis
- Time Complexity : O( y * n*logn)
Where y = log( abs(Mat[0][0] - Mat[n-1][n-1]) )
- We call the getElementsGreaterThanOrEqual function log ( abs(Mat[0][0] – Mat[n-1][n-1]) ) times
- Time complexity of getElementsGreaterThanOrEqual is O(n logn) since there we do binary search n times.
USING ARRAY:
We will make a new array and will copy all the contents of matrix in this array. After that we will sort that array and find kth smallest element. This will be so easier.
C++
#include <bits/stdc++.h>
using namespace std;
int kthSmallest( int mat[4][4], int n, int k)
{
int a[n*n];
int v = 0;
for ( int i = 0; i < n; i++)
{
for ( int j = 0; j < n; j++)
{
a[v] = mat[i][j];
v++;
}
}
sort(a, a + (n*n));
int result = a[k - 1];
return result;
}
int main()
{
int mat[4][4] = { { 10, 20, 30, 40 },
{ 15, 25, 35, 45 },
{ 25, 29, 37, 48 },
{ 32, 33, 39, 50 } };
int res = kthSmallest(mat, 4, 7);
cout << "7th smallest element is " << res;
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
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);
}
static int kthSmallest( int [][]mat, int n, int k)
{
int [] a= new int [n*n];
int v= 0 ;
for ( int i= 0 ;i<n;i++){
for ( int j= 0 ;j<n;j++){
a[v]=mat[i][j];
v++;
}
}
Arrays.sort(a);
int result=a[k- 1 ];
return result;
}
}
|
Python3
def kthSmallest(mat, n, k):
a = [ 0 for i in range (n * n)]
v = 0
for i in range (n):
for j in range (n):
a[v] = mat[i][j]
v + = 1
a.sort()
result = a[k - 1 ]
return result
mat = [ [ 10 , 20 , 30 , 40 ],
[ 15 , 25 , 35 , 45 ],
[ 25 , 29 , 37 , 48 ],
[ 32 , 33 , 39 , 50 ] ]
res = kthSmallest(mat, 4 , 7 )
print ( "7th smallest element is " + str (res))
|
C#
using System;
using System.Collections.Generic;
public class GFG {
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);
}
static int kthSmallest( int [,]mat, int n, int k)
{
int [] a = new int [n*n];
int v = 0;
for ( int i = 0; i < n; i++)
{
for ( int j = 0; j < n; j++)
{
a[v] = mat[i, j];
v++;
}
}
Array.Sort(a);
int result = a[k - 1];
return result;
}
}
|
Javascript
<script>
function kthSmallest(mat, n, k)
{
let a = new Array(n*n)
let v=0
for (let i = 0; i < n; i++)
{
for (let j = 0; j < n; j++)
{
a[v] = mat[i][j];
v++;
}
}
a.sort();
let result = a[k - 1];
return result;
}
let mat = [ [ 10, 20, 30, 40 ],
[ 15, 25, 35, 45 ],
[ 25, 29, 37, 48 ],
[ 32, 33, 39, 50 ] ]
let res = kthSmallest(mat, 4, 7)
document.write( "7th smallest element is " + res, "</br>" )
</script>
|
Output
7th smallest element is 30
Time Complexity: O(N2log(N2)) , We have array of N2 elements,for sorting them time will be N2log(N2).
Auxiliary Space: O(N2)
Using Priority queue approach
C++14
#include <bits/stdc++.h>
using namespace std;
int kthSmallest(vector<vector< int >>& matrix, int k) {
int i,j,n=matrix.size();
priority_queue< int > maxH;
if (k==1)
return matrix[0][0];
for (i=0;i<n;i++)
{
for (j=0;j<n;j++)
{
maxH.push(matrix[i][j]);
if (maxH.size()>k)
maxH.pop();
}
}
return maxH.top();
}
int main() {
vector<vector< int >> matrix = {{1,5,9},{10,11,13},{12,13,15}};
int k = 8;
cout << "8th smallest element is " << kthSmallest(matrix,k);
return 0;
}
|
Java
import java.util.*;
import java.io.*;
public class Main {
public static int kthSmallest( int [][] matrix, int k)
{
int i, j, n = matrix.length;
PriorityQueue<Integer> maxH = new PriorityQueue<>(
Collections.reverseOrder());
if (k == 1 )
return matrix[ 0 ][ 0 ];
for (i = 0 ; i < n; i++) {
for (j = 0 ; j < n; j++) {
maxH.add(matrix[i][j]);
if (maxH.size() > k)
maxH.poll();
}
}
return maxH.peek();
}
public static void main(String[] args)
{
int [][] matrix = { { 1 , 5 , 9 },
{ 10 , 11 , 13 },
{ 12 , 13 , 15 } };
int k = 8 ;
System.out.print( "8th smallest element is "
+ kthSmallest(matrix, k));
}
}
|
Python3
import heapq
def kthSmallest(matrix, k):
n = len (matrix)
maxH = []
for i in range (n):
for j in range (n):
heapq.heappush(maxH, - matrix[i][j])
if len (maxH) > k:
heapq.heappop(maxH)
return - maxH[ 0 ]
matrix = [[ 1 , 5 , 9 ], [ 10 , 11 , 13 ], [ 12 , 13 , 15 ]]
k = 8
print ( "8th smallest element is" , kthSmallest(matrix, k))
|
C#
using System;
using System.Collections.Generic;
public class GFG {
public static int kthSmallest( int [,] matrix, int k)
{
int i, j, n = matrix.GetLength(0);
List< int > maxH = new List< int >();
if (k == 1)
return matrix[0,0];
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
maxH.Add(matrix[i,j]);
if (maxH.Count > k){
maxH.Sort((a, b) => b.CompareTo(a));
maxH.RemoveAt(0);
}
}
}
maxH.Sort((a, b) => b.CompareTo(a));
return maxH[0];
}
public static void Main(String[] args)
{
int [,] matrix = { { 1, 5, 9 },
{ 10, 11, 13 },
{ 12, 13, 15 } };
int k = 8;
Console.Write( "8th smallest element is "
+ kthSmallest(matrix, k));
}
}
|
Javascript
<script>
function kthSmallest(matrix, k) {
let i;
let j;
let n = matrix.length;
maxH = [];
if (k==1) return matrix[0][0];
for (i=0;i<n;i++){
for (j=0;j<n;j++){
maxH.push(matrix[i][j]);
maxH.sort((a, b) => (b-a));
if (maxH.length>k) maxH.shift();
}
}
return maxH[0];
}
let matrix = [[1,5,9],[10,11,13],[12,13,15]];
let k = 8;
document.write( "8th smallest element is " + kthSmallest(matrix,k));
</script>
|
Output
8th smallest element is 13
Time Complexity: O(log(k)*n2)
Auxiliary Space: O(n)
This article is contributed by Aarti_Rathi. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above
Feeling lost in the world of random DSA topics, wasting time without progress? It’s time for a change! Join our DSA course, where we’ll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!