Open In App
Related Articles

Find median in row wise sorted matrix

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Report issue
Report

We are given a row-wise sorted matrix of size r*c, we need to find the median of the matrix given. It is assumed that r*c is always odd.

Examples: 

Input:
1 3 5
2 6 9
3 6 9
Output:
Median is 5
If we put all the values in a sorted array A[] = 1 2 3 3 5 6 6 9 9)

Input:
1 3 4
2 5 6
7 8 9
Output:
Median is 5

Simple Method: The simplest method to solve this problem is to store all the elements of the given matrix in an array of size r*c. Then we can either sort the array and find the median element in O(r*clog(r*c)),

C++

#include <iostream>
#include <vector>
#include <algorithm>
 
using namespace std;
 
double find_median(vector<vector<int>> matrix) {
    // Flatten the matrix into a 1D array
    vector<int> arr;
    for (int i = 0; i < matrix.size(); i++) {
        for (int j = 0; j < matrix[0].size(); j++) {
            arr.push_back(matrix[i][j]);
        }
    }
 
    // Sort the array
    sort(arr.begin(), arr.end());
 
    // Find the median element
    int mid = arr.size() / 2;
    double median;
    if (arr.size() % 2 == 0) {
        median = (arr[mid-1] + arr[mid]) / 2.0;
    } else {
        median = arr[mid];
    }
 
    return median;
}
 
int main() {
    // Example 1
    vector<vector<int>> matrix1 = {{1, 3, 5},
                                   {2, 6, 9},
                                   {3, 6, 9}};
    double median1 = find_median(matrix1);
    cout << "Median of matrix1: " << median1 << endl;
 
    // Example 2
    vector<vector<int>> matrix2 = {{1, 3, 4},
                                   {2, 5, 6},
                                   {7, 8, 9}};
    double median2 = find_median(matrix2);
    cout << "Median of matrix2: " << median2 << endl;
 
    return 0;
}

                    

Java

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
 
public class Main {
 
  public static double findMedian(List<List<Integer>> matrix) {
    // Flatten the matrix into a 1D list
    List<Integer> list = new ArrayList<Integer>();
    for (int i = 0; i < matrix.size(); i++) {
      for (int j = 0; j < matrix.get(0).size(); j++) {
        list.add(matrix.get(i).get(j));
      }
    }
 
    // Sort the list
    Collections.sort(list);
 
    // Find the median element
    int mid = list.size() / 2;
    double median;
    if (list.size() % 2 == 0) {
      median = (list.get(mid - 1) + list.get(mid)) / 2.0;
    } else {
      median = list.get(mid);
    }
 
    return median;
  }
 
  public static void main(String[] args) {
    // Example 1
    List<List<Integer>> matrix1 = new ArrayList<List<Integer>>();
    matrix1.add(new ArrayList<Integer>(){{add(1); add(3); add(5);}});
    matrix1.add(new ArrayList<Integer>(){{add(2); add(6); add(9);}});
    matrix1.add(new ArrayList<Integer>(){{add(3); add(6); add(9);}});
    double median1 = findMedian(matrix1);
    System.out.println("Median of matrix1: " + median1);
 
    // Example 2
    List<List<Integer>> matrix2 = new ArrayList<List<Integer>>();
    matrix2.add(new ArrayList<Integer>(){{add(1); add(3); add(4);}});
    matrix2.add(new ArrayList<Integer>(){{add(2); add(5); add(6);}});
    matrix2.add(new ArrayList<Integer>(){{add(7); add(8); add(9);}});
    double median2 = findMedian(matrix2);
    System.out.println("Median of matrix2: " + median2);
  }
}

                    

Python

def find_median(matrix):
    # Flatten the matrix into a 1D array
    arr = []
    for i in range(len(matrix)):
        for j in range(len(matrix[0])):
            arr.append(matrix[i][j])
     
    # Sort the array
    arr.sort()
     
    # Find the median element
    mid = len(arr) // 2
    if len(arr) % 2 == 0:
        median = (arr[mid-1] + arr[mid]) / 2
    else:
        median = arr[mid]
     
    return median
# Example 1
matrix1 = [[1, 3, 5],
           [2, 6, 9],
           [3, 6, 9]]
median1 = find_median(matrix1)
print("Median of matrix1:", median1)
 
# Example 2
matrix2 = [[1, 3, 4],
           [2, 5, 6],
           [7, 8, 9]]
median2 = find_median(matrix2)
print("Median of matrix2:", median2)

                    

C#

using System;
using System.Collections.Generic;
using System.Linq;
 
namespace MedianMatrix
{
    class Program
    {
        static double FindMedian(List<List<int>> matrix)
        {
            // Flatten the matrix into a 1D array
            List<int> arr = new List<int>();
            foreach (var row in matrix)
            {
                arr.AddRange(row);
            }
 
            // Sort the array
            arr.Sort();
 
            // Find the median element
            int mid = arr.Count / 2;
            double median;
            if (arr.Count % 2 == 0)
            {
                median = (arr[mid - 1] + arr[mid]) / 2.0;
            }
            else
            {
                median = arr[mid];
            }
 
            return median;
        }
 
        static void Main(string[] args)
        {
            // Example 1
            List<List<int>> matrix1 = new List<List<int>>
            {
                new List<int> { 1, 3, 5 },
                new List<int> { 2, 6, 9 },
                new List<int> { 3, 6, 9 }
            };
            double median1 = FindMedian(matrix1);
            Console.WriteLine("Median of matrix1: " + median1);
 
            // Example 2
            List<List<int>> matrix2 = new List<List<int>>
            {
                new List<int> { 1, 3, 4 },
                new List<int> { 2, 5, 6 },
                new List<int> { 7, 8, 9 }
            };
            double median2 = FindMedian(matrix2);
            Console.WriteLine("Median of matrix2: " + median2);
        }
    }
}

                    

Javascript

function findMedian(matrix) {
    // Flatten the matrix into a 1D array
    const arr = matrix.reduce((acc, row) => acc.concat(row), []);
 
    // Sort the array
    arr.sort((a, b) => a - b);
 
    // Find the median element
    const mid = Math.floor(arr.length / 2);
    let median;
    if (arr.length % 2 === 0) {
        median = (arr[mid - 1] + arr[mid]) / 2.0;
    } else {
        median = arr[mid];
    }
 
    return median;
}
 
// Example 1
const matrix1 = [
    [1, 3, 5],
    [2, 6, 9],
    [3, 6, 9]
];
const median1 = findMedian(matrix1);
console.log("Median of matrix1: " + median1);
 
// Example 2
const matrix2 = [
    [1, 3, 4],
    [2, 5, 6],
    [7, 8, 9]
];
const median2 = findMedian(matrix2);
console.log("Median of matrix2: " + median2);
 
// This code is contributed by shivamgupta0987654321

                    

Output
Median of matrix1: 5
Median of matrix2: 5


Another Approach we can use the approach discussed here to find the median in O(r*c). Auxiliary space required will be O(r*c) in both cases.

An efficient approach for this problem is to use a binary search algorithm. The idea is that for a number to be median there should be exactly (n/2) numbers that are less than this number. So, we try to find the count of numbers less than all the numbers. Below is the step-by-step algorithm for this approach: 

Algorithm:  

  1. First, we find the minimum and maximum elements in the matrix. The minimum element can be easily found by comparing the first element of each row, and similarly, the maximum element can be found by comparing the last element of each row.
  2. Then we use binary search on our range of numbers from minimum to maximum, we find the mid of the min and max and get a count of numbers less than or equal to our mid. And accordingly change the min or max.
  3. For a number to be median, there should be (r*c)/2 numbers smaller than that number. So for every number, we get the count of numbers less than or equal to that by using upper_bound() in each row of the matrix, if it is less than the required count, the median must be greater than the selected number, else the median must be less than or equal to the selected number.

Below is the implementation of the above approach:

C++

// C++ program to find median of a matrix
// sorted row wise
#include<bits/stdc++.h>
using namespace std;
 
const int MAX = 100;
 
// function to find median in the matrix
int binaryMedian(int m[][MAX], int r ,int c)
{
    int min = INT_MAX, max = INT_MIN;
    for (int i=0; i<r; i++)
    {
        // Finding the minimum element
        if (m[i][0] < min)
            min = m[i][0];
 
        // Finding the maximum element
        if (m[i][c-1] > max)
            max = m[i][c-1];
    }
 
    int desired = (r * c + 1) / 2;
    while (min < max)
    {
        int mid = min + (max - min) / 2;
        int place = 0;
 
        // Find count of elements smaller than or equal to mid
        for (int i = 0; i < r; ++i)
            place += upper_bound(m[i], m[i]+c, mid) - m[i];
        if (place < desired)
            min = mid + 1;
        else
            max = mid;
    }
    return min;
}
 
// driver program to check above functions
int main()
{
    int r = 3, c = 3;
    int m[][MAX]= { {1,3,5}, {2,6,9}, {3,6,9} };
    cout << "Median is " << binaryMedian(m, r, c) << endl;
    return 0;
}

                    

Java

// Java program to find median of a matrix
// sorted row wise
import java.util.Arrays;
 
public class MedianInRowSorted {
    // function to find median in the matrix
    static int binaryMedian(int m[][], int r, int c) {
        int max = Integer.MIN_VALUE;
        int min = Integer.MAX_VALUE;
 
        for (int i = 0; i < r; i++) {
            // Finding the minimum element
            if (m[i][0] < min)
                min = m[i][0];
 
            // Finding the maximum element
            if (m[i] > max)
                max = m[i];
        }
 
        int desired = (r * c + 1) / 2;
        while (min < max) {
            int mid = min + (max - min) / 2;
            int place = 0;
            int get = 0;
 
            // Find count of elements smaller than or equal
            // to mid
            for (int i = 0; i < r; ++i) {
                get = Arrays.binarySearch(m[i], mid);
 
                // If element is not found in the array the
                // binarySearch() method returns
                // (-(insertion_point) - 1). So once we know
                // the insertion point we can find elements
                // Smaller than the searched element by the
                // following calculation
                if (get < 0)
                    get = Math.abs(get) - 1;
 
                // If element is found in the array it
                // returns the index(any index in case of
                // duplicate). So we go to last index of
                // element which will give the number of
                // elements smaller than the number
                // including the searched element.
                else {
                    while (get < c && m[i][get] == mid)
                        get += 1;
                }
 
                place = place + get;
            }
 
            if (place < desired)
                min = mid + 1;
            else
                max = mid;
        }
        return min;
    }
 
    // Driver Program to test above method.
    public static void main(String[] args) {
        int r = 3, c = 3;
        int m[][] = { { 1, 3, 5 }, { 2, 6, 9 }, { 3, 6, 9 } };
 
        System.out.println("Median is " + binaryMedian(m, r, c));
    }
}

                    

Python3

# Python program to find median of matrix
# sorted row wise
 
from bisect import bisect_right as upper_bound
 
MAX = 100;
 
# Function to find median in the matrix
def binaryMedian(m, r, d):
    mi = m[0][0]
    mx = 0
    for i in range(r):
        if m[i][0] < mi:
            mi = m[i][0]
        if m[i][d-1] > mx :
            mx =  m[i][d-1]
     
    desired = (r * d + 1) // 2
     
    while (mi < mx):
        mid = mi + (mx - mi) // 2
        place = [0];
         
        # Find count of elements smaller than or equal to mid
        for i in range(r):
             j = upper_bound(m[i], mid)
             place[0] = place[0] + j
        if place[0] < desired:
            mi = mid + 1
        else:
            mx = mid
    print ("Median is", mi)
    return   
     
# Driver code
r, d = 3, 3
 
m = [ [1, 3, 5], [2, 6, 9], [3, 6, 9]]
binaryMedian(m, r, d)
 
# This code is contributed by Sachin BIsht

                    

C#

// C# program to find median
// of a matrix sorted row wise
using System;
class MedianInRowSorted{
 
// Function to find median
// in the matrix
static int binaryMedian(int [,]m,
                        int r, int c)
{
  int max = int.MinValue;
  int min = int.MaxValue;
 
  for(int i = 0; i < r; i++)
  {
    // Finding the minimum
    // element
    if(m[i, 0] < min)
      min = m[i, 0];
 
    // Finding the maximum
    // element
    if(m[i, c - 1] > max)
      max = m[i, c - 1];
  }
 
  int desired = (r * c + 1) / 2;
  while(min < max)
  {
    int mid = min + (max - min) / 2;
    int place = 0;
    int get = 0;
 
    // Find count of elements
    // smaller than or equal to mid
    for(int i = 0; i < r; ++i)
    {
      get = Array.BinarySearch(
            GetRow(m, i), mid);
 
      // If element is not found
      // in the array the binarySearch()
      // method returns (-(insertion_
      // point) - 1). So once we know
      // the insertion point we can
      // find elements Smaller than
      // the searched element by the
      // following calculation
      if(get < 0)
        get = Math.Abs(get) - 1;
 
      // If element is found in the
      // array it returns the index(any
      // index in case of duplicate). So
      // we go to last index of element
      // which will give  the number of
      // elements smaller than the number
      // including the searched element.
      else
      {
        while(get < GetRow(m, i).GetLength(0) &&
              m[i, get] == mid)
          get += 1;
      }
 
      place = place + get;
    }
 
    if (place < desired)
      min = mid + 1;
    else
      max = mid;
  }
  return min;
}
 
public static int[] GetRow(int[,] matrix,
                           int row)
{
  var rowLength = matrix.GetLength(1);
  var rowVector = new int[rowLength];
 
  for (var i = 0; i < rowLength; i++)
    rowVector[i] = matrix[row, i];
 
  return rowVector;
}
   
// Driver code
public static void Main(String[] args)
{
  int r = 3, c = 3;
  int [,]m = {{1,3,5},
              {2,6,9},
              {3,6,9} };
 
  Console.WriteLine("Median is " +
                     binaryMedian(m, r, c));
}
}
 
// This code is contributed by Princi Singh

                    

Javascript

<script>
 
// Javascript program to find median
// of a matrix sorted row wise
 
 
// Function to find median
// in the matrix
function binaryMedian(m, r, c)
{
  var max = -1000000000;
  var min = 1000000000;
 
  for(var i = 0; i < r; i++)
  {
    // Finding the minimum
    // element
    if(m[i][0] < min)
      min = m[i][0];
 
    // Finding the maximum
    // element
    if(m[i] > max)
      max = m[i];
  }
 
  var desired =  parseInt((r * c + 1) / 2);
  while(min < max)
  {
    var mid = min + parseInt((max - min) / 2);
    var place = 0;
    var get = 0;
 
    // Find count of elements
    // smaller than or equal to mid
    for(var i = 0; i < r; ++i)
    {
        var tmp = GetRow(m, i);
        for(var j = tmp.length; j>=0; j--)
        {
            if(tmp[j] <= mid)
            {
                get = j+1;
                break;
            }
        }
 
      // If element is not found
      // in the array the binarySearch()
      // method returns (-(insertion_
      // point) - 1). So once we know
      // the insertion point we can
      // find elements Smaller than
      // the searched element by the
      // following calculation
      if(get < 0)
        get = Math.abs(get) - 1;
 
      // If element is found in the
      // array it returns the index(any
      // index in case of duplicate). So
      // we go to last index of element
      // which will give  the number of
      // elements smaller than the number
      // including the searched element.
      else
      {
        while(get < GetRow(m, i).length &&
              m[i][get] == mid)
          get += 1;
      }
 
      place = place + get;
    }
 
    if (place < desired)
      min = mid + 1;
    else
      max = mid;
  }
  return min;
}
 
function GetRow(matrix, row)
{
  var rowLength = matrix[0].length;
  var rowVector = Array(rowLength).fill(0);
 
  for (var i = 0; i < rowLength; i++)
    rowVector[i] = matrix[row][i];
 
  return rowVector;
}
   
// Driver code
var r = 3, c = 3;
var m = [[1,3,5],
            [2,6,9],
            [3,6,9]];
document.write("Median is " +
                   binaryMedian(m, r, c));
 
 
// This code is contributed by rutvik_56.
</script>

                    

Output
Median is 5


Time Complexity: O(32 * r * log(c)). The upper bound function will take log(c) time and is performed for each row. And since the numbers will be max of 32 bit, so binary search of numbers from min to max will be performed in at most 32 ( log2(2^32) = 32 ) operations. 
Auxiliary Space: O(1) 

Method 2 – Using a min heap – Priority Queue 
When we need to find the nth smallest element in a row or a column sorted matrix, we can use a min heap and a class node{val,row,col}, 
Since the matrix is row sorted the smallest element will be one among the first elements of all row ,
so push all first element of rows in the min heap,  then for top element in heap push the second column element in that row ,if it is smallest it will be on top, or the other smallest element will be on top.
Repeat this process of popping the top elements till (r*c)/2.

In this problem this concept is used to find the median of the row sorted matrix.

C++

#include<bits/stdc++.h>
using namespace std;
 
class node{
    public:
        int data;
        int row;
        int col;
         
        node(int d, int r, int c){
            row = r;
            col = c;
            data = d;
        }
};
 
class compare{
    public:
    bool operator()(node* a, node* b){
        return a->data > b->data;
    }
};
 
class Solution{  
public:
    int median(vector<vector<int>> &matrix, int R, int C){
        priority_queue<node*, vector<node*>, compare>minheap;
        int count = 0, median = -1;
        int medianindex = (R*C)/2;
         
        for(int i = 0; i<R; i++){
            node* temp = new node(matrix[i][0], i, 0);
            minheap.push(temp);
        }
         
         
        while(count <= medianindex){
            node* top = minheap.top();
            minheap.pop();
            int row = top->row;
            int col = top->col;
            median = top->data;
             
            count++;
            if(col+1 < C){
                col++;
                 node* temp = new node(matrix[row][col], row, col);
                 minheap.push(temp);
            }
        }
        return median;
    }
 
};
 
int main()
{
     
        int r=3;
        int c=3;
         
        vector<vector<int>> matrix={{1, 3, 5},
                                    {2, 6, 9},
                                    {3, 6, 9}};
        
        Solution obj;
        cout<<obj.median(matrix, r, c)<<endl;       
     
    return 0;
}

                    

Java

// Node class contains 3 fields - data, row, and col.
// It initializes the values of these fields in its
// constructor.
import java.util.*;
class Node {
    int data; // contains the value of the current node
    int row; // contains the row number of the current node
             // in the matrix
    int col; // contains the column number of the current
             // node in the matrix
    Node(int d, int r, int c)
    {
        row = r;
        col = c;
        data = d;
    }
}
 
// Compare class implements the Comparator interface and
// overrides the compare method. It is used to compare 2
// nodes and determine the order in which they should be
// inserted in the min heap.
class Compare implements Comparator<Node> {
    public int compare(Node a, Node b)
    {
        // if a.data is greater than b.data, return 1
        // else return -1
        return a.data > b.data ? 1 : -1;
    }
}
 
// Solution class contains the main logic to find median
class Solution {
    public int median(int[][] matrix, int R, int C)
    {
        // minheap is a priority queue implemented using min
        // heap data structure. It stores the nodes in
        // ascending order based on their values.
        PriorityQueue<Node> minheap
            = new PriorityQueue<>(new Compare());
        int count = 0,
            median
            = -1; // count variable to keep track of the
                  // number of nodes processed so far
        // median variable to store the median value in the
        // end medianindex is the index of the median in the
        // matrix
        int medianindex = (R * C) / 2;
        // Push the first elements of each row in the min
        // heap
        for (int i = 0; i < R; i++) {
            Node temp = new Node(matrix[i][0], i, 0);
            minheap.add(temp);
        }
 
        // Repeat until we reach the medianindex
        while (count <= medianindex) {
            Node top
                = minheap.poll(); // remove the node with
                                  // the smallest value from
                                  // the min heap
            int row = top.row;
            int col = top.col;
            median = top.data;
 
            count++;
            // if the current node is not the last element
            // in its row, push the next element from the
            // same row into the min heap
            if (col + 1 < C) {
                col++;
                Node temp
                    = new Node(matrix[row][col], row, col);
                minheap.add(temp);
            }
        }
        return median;
    }
}
 
// Main class contains the main method
public class Main {
    public static void main(String[] args)
    {
        int r = 3; // number of rows in the matrix
        int c = 3; // number of columns in the matrix
        int[][] matrix
            = { { 1, 3, 5 }, { 2, 6, 9 }, { 3, 6, 9 } };
 
        Solution obj = new Solution();
        // Call the median method from the Solution class
        // and print the result
        System.out.println(obj.median(matrix, r, c));
    }
}
//This Code is Contributed by chinmaya121221

                    

Python3

# import library for min heap
import heapq
from typing import List
 
# Node class
    # contains the value of the current node
    # contains the row number of the current node
    # in the matrix
    # contains the column number of the current
    # node in the matrix
class Node:
    def __init__(self, data: int, row: int, col: int):
        self.data = data
        self.row = row
        self.col = col
    def __lt__(self, other):
        return self.data < other.data
 
# Solution class contains the main logic to find median
class Solution:
    # median function
    def median(self, matrix, R, C):
        # minheap is a priority queue implemented using min
        # heap data structure. It stores the nodes in
        # ascending order based on their values.
        minheap = []
        # count variable to keep track of the
        # number of nodes processed so far
        count = 0
        # median variable to store the median value in the
        # end medianindex is the index of the median in the
        # matrix
        median = -1
        medianindex = (R * C) // 2
 
        # Push the first elements of each row in the min
        # heap
        for i in range(R):
            temp = Node(matrix[i][0], i, 0)
            heapq.heappush(minheap, temp)
 
        # Repeat until we reach the medianindex
        while count <= medianindex:
            top = heapq.heappop(minheap) # remove the node with
                                  # the smallest value from
                                  # the min heap
            row = top.row
            col = top.col
            median = top.data
 
            count += 1
            # if the current node is not the last element
            # in its row, push the next element from the
            # same row into the min heap
            if col + 1 < C:
                col += 1
                temp = Node(matrix[row][col], row, col)
                heapq.heappush(minheap, temp)
 
        return median
 
# Main class contains the main method
if __name__ == "__main__":
    r = 3
    c = 3
    matrix = [[1, 3, 5], [2, 6, 9], [3, 6, 9]]
 
    obj = Solution()
    print(obj.median(matrix, r, c))

                    

C#

//c# code for the above approach
using System;
using System.Collections.Generic;
 
public class Node {
    public int Data { get; set; } 
  // contains the value of the current node
    public int Row { get; set; }
  // contains the row number of the current node
   // in the matrix
    public int Col { get; set; }
  // contains the column number of the current
   // node in the matrix
 
    public Node(int data, int row, int col) {
        Data = data;
        Row = row;
        Col = col;
    }
}
 
public class Solution {
    public int Median(List<List<int>> matrix, int R, int C) {
        var minHeap = new PriorityQueue<Node>((a, b) =>
                          a.Data.CompareTo(b.Data));
        // minheap is a priority queue implemented using min
        // heap data structure. It stores the nodes in
        // ascending order based on their values.
 
        int count = 0, median = -1;
      // count variable to keep track of the
          // number of nodes processed so far
        // median variable to store the median value in the
        // end medianindex is the index of the median in the
        // matrix
        int medianIndex = (R * C) / 2;
        // Push the first elements of each row in the min
        // heap
        for (int i = 0; i < R; i++) {
            var temp = new Node(matrix[i][0], i, 0);
            minHeap.Enqueue(temp);
        }
        // Repeat until we reach the medianindex
        while (count <= medianIndex) {
            var top = minHeap.Dequeue();
          // remove the node with
          // the smallest value from
           // the min heap
            int row = top.Row;
            int col = top.Col;
            median = top.Data;
 
            count++;
            // if the current node is not the last element
            // in its row, push the next element from the
            // same row into the min heap
 
            if (col + 1 < C) {
                col++;
                var temp = new Node(matrix[row][col], row, col);
                minHeap.Enqueue(temp);
            }
        }
 
        return median;
    }
}
 
public class PriorityQueue<T> {
    private List<T> heap;
    private Comparison<T> comparison;
// Compare class implements the Comparator interface and
// overrides the compare method. It is used to compare 2
// nodes and determine the order in which they should be
// inserted in the min heap.
 
    public PriorityQueue(Comparison<T> comparison) {
        heap = new List<T>();
        this.comparison = comparison;
    }
 
    public int Count {
        get { return heap.Count; }
    }
 // custom class to implement the enqueue function in priority
  //queue
    public void Enqueue(T item) {
        heap.Add(item);
        int i = heap.Count - 1;
 
        while (i > 0) {
            int parent = (i - 1) / 2;
            if (comparison(heap[parent], item) <= 0) {
                break;
            }
            heap[i] = heap[parent];
            i = parent;
        }
 
        heap[i] = item;
    }
 // custom class to implement the dequeue function in priority
  //queue
 
    public T Dequeue() {
        T item = heap[0];
        int lastIndex = heap.Count - 1;
        heap[0] = heap[lastIndex];
        heap.RemoveAt(lastIndex);
        lastIndex--;
 
        int i = 0;
        while (true) {
            int leftChild = 2 * i + 1;
            int rightChild = 2 * i + 2;
 
            if (leftChild > lastIndex) {
                break;
            }
 
            int minChild = leftChild;
 
 if (rightChild <= lastIndex &&
     comparison(heap[rightChild], heap[leftChild]) < 0)
 {
                minChild = rightChild;
            }
 
            if (comparison(heap[i], heap[minChild]) <= 0) {
                break;
            }
 
            T temp = heap[i];
            heap[i] = heap[minChild];
            heap[minChild] = temp;
 
            i = minChild;
        }
 
        return item;
    }
 
    public T Peek() {
        return heap[0];
    }
}
 
public class GFG {
    public static void Main() {
        int R = 3;
        int C = 3;
 
        var matrix = new List<List<int>> {
            new List<int> {1, 3, 5},
            new List<int> {2, 6, 9},
            new List<int> {3, 6, 9}
        };
 
        var obj = new Solution();
        Console.WriteLine(obj.Median(matrix, R, C));
    }
}

                    

Javascript

class Node {
  constructor(data, row, col) {
    this.data = data; // data to be stored in the node
    this.row = row; // row index of the data in the matrix
    this.col = col; // column index of the data in the matrix
  }
}
 
class MinHeap {
  constructor(compareFunc) {
    this.heap = []; // array to store the heap
    this.compare = compareFunc; // comparison function to determine the priority of nodes
  }
 
  push(node) {
    this.heap.push(node); // add the node to the end of the heap
    let current = this.heap.length - 1;
 
    // bubble up the node until the heap property is satisfied
    while (current > 0) {
      let parent = Math.floor((current - 1) / 2); // index of the parent node
      if (this.compare(this.heap[current], this.heap[parent])) { // if the child node has higher priority than its parent node
        let temp = this.heap[current];
        this.heap[current] = this.heap[parent]; // swap the child node with its parent node
        this.heap[parent] = temp;
        current = parent; // update the index of the child node to be its parent node
      } else {
        break; // stop bubbling up if the child node has lower priority than its parent node
      }
    }
  }
 
  pop() {
    if (this.heap.length === 0) return null; // if the heap is empty, return null
    let result = this.heap[0]; // retrieve the root node
    this.heap[0] = this.heap.pop(); // move the last node to the root position
    let current = 0;
 
    // bubble down the root node until the heap property is satisfied
    while (true) {
      let left = 2 * current + 1; // index of the left child node
      let right = 2 * current + 2; // index of the right child node
      let smallest = current;
 
      // find the node with highest priority among the root node and its children
      if (
        left < this.heap.length &&
        this.compare(this.heap[left], this.heap[smallest])
      ) {
        smallest = left;
      }
 
      if (
        right < this.heap.length &&
        this.compare(this.heap[right], this.heap[smallest])
      ) {
        smallest = right;
      }
 
      if (smallest === current) {
        break; // stop bubbling down if the root node has higher priority than its children
      } else {
        let temp = this.heap[current];
        this.heap[current] = this.heap[smallest]; // swap the root node with its child node that has higher priority
        this.heap[smallest] = temp;
        current = smallest; // update the index of the root node to be its child node
      }
    }
 
    return result; // return the popped node
  }
 
  size() {
    return this.heap.length; // return the size of the heap
  }
 
  peek() {
    return this.heap.length > 0 ? this.heap[0] : null; // return the root node if the heap is not empty, otherwise return null
  }
}
 
class Solution {
  median(matrix, R, C) {
    let minHeap = new MinHeap((a, b) => a.data < b.data); // create a min heap using the comparison function that compares the data values of nodes
    let count = 0; // count the number of nodes popped from the heap
    let median = -1; //
    let medianIndex = (R * C) / 2;
 
    for (let i = 0; i < R; i++) {
      let temp = new Node(matrix[i][0], i, 0);
      minHeap.push(temp);
    }
 
    while (count <= medianIndex) {
      let top = minHeap.pop();
      let row = top.row;
      let col = top.col;
      median = top.data;
 
      count++;
 
      if (col + 1 < C) {
        col++;
        let temp = new Node(matrix[row][col], row, col);
        minHeap.push(temp);
      }
    }
 
    return median;
  }
}
 
let r = 3;
let c = 3;
let matrix = [
  [1, 3, 5],
  [2, 6, 9],
  [3, 6, 9],
];
 
let obj = new Solution();
console.log(obj.median(matrix, r, c));

                    

Output
5


Time complexity – O( r*c/2 * log(r) ), Since we are going to insert and remove the top element in priority queue r*c/2 times and every time the priority queue will be having elements in it.
Auxiliary Space = O((r*c)log(r*c)) – For creating a min heap, with the maximum number of elements equal to r*c/2
 



Last Updated : 20 Dec, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads