Find median in row wise sorted matrix in C++

C++Server Side ProgrammingProgramming

In this problem, we are given a 2D array mat[r][c] whose elements are sorted row-wise. Our task is to Find median in a row-wise sorted matrix.

Description − we need to find the median of elements of the matrix.

Let’s take an example to understand the problem,

Input

mat = {
{2, 4, 7},
{5, 6, 8},
{4, 8, 9}
}

Output

6

Explanation

The elements of the matrix stored in array are &minus

{2, 4, 4, 5, 6, 7, 8, 8, 9}
The median is 6.

Solution Approach

A simple solution to the problem is by storing all elements of the array. Then finding the median element by sorting the array.

A more effective solution to the problem is finding the median element using the fact the is has exactly (r*c)/2 smaller element in the matrix. And we will find the element in the array that follows this condition. For this we will use the binary search on the matrix taking the smallest and largest element of the matrix and then we will find the middle of the range and check the number of smaller elements in it. If it equal to r*c/2 then return the number. If it is greater than (r*c)/2, then we will change the largest element to the element smaller than the middle found and do the same for smallest if the count is smaller than (r*c)/2.

The count of elements smaller than the middle element, we can either count all elements row-wise by finding the index of the first element greater than middle or simply use the upper_bound which is an inbuilt function in c++.

Program to illustrate the working of our solution,

Example

Live Demo

#include<bits/stdc++.h>
using namespace std;
#define c 3
#define r 3
int findMedian(int mat[][c]) {
int smallest = INT_MAX, largest = INT_MIN;
for (int i=0; i<r; i++) {
if (mat[i][0] < smallest)
smallest = mat[i][0];
if (mat[i][c-1] > largest)
largest = mat[i][c-1];
}
while (smallest < largest){
int mid = smallest + (largest - smallest) / 2;
int smallCount = 0;
for (int i = 0; i < r; ++i)
smallCount += upper_bound(mat[i], mat[i]+c, mid) -
mat[i];
if (smallCount < ( (r * c + 1) / 2 ))
smallest = mid + 1;
else
largest = mid;
}
return smallest;
}
int main(){
int mat[][c]= { {2, 5, 7}, {4, 6, 8}, {1, 8, 9} };
cout<<"The median of the matrix is "<<findMedian(mat);
return 0;
}

Output

The median of the matrix is 6
Published on 12-Mar-2021 06:43:22