Open In App

Median of an Array

Last Updated : 04 Mar, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an array arr[], the task is to find the median of this array. The median of an array of size n is defined as the middle element when n is odd and the average of the middle two elements when n is even.

Examples: 

Input: arr[] = [12, 3, 5, 7, 4, 19, 26]
Output:
Explanation: Sorted sequence of given array arr[] = [3, 4, 5, 7, 12, 19, 26] Since the number of elements is odd, the median is 4th element in the sorted sequence of given array arr[], which is 7

Input: arr[] = [12, 3, 5, 7, 4, 26] 
Output: 6
Explanation: Since number of elements are even, median is average of 3rd and 4th element in sorted sequence of given array arr[], which means (5 + 7)/2 = 6

[Naive Approach] By Sorting the Array - O(n log n) Time and O(1) Space

The basic idea is to sort the array and check the array size if it is odd then return the middle otherwise return the average of the two middle elements.

C++
#include<iostream>
#include<vector>
#include <algorithm>
using namespace std;

double findMedian(vector<int> &arr) {
  	int n = arr.size();
  
    // First we sort the array
    sort(arr.begin(), arr.end());

    // check for even case
    if (n % 2 != 0)
        return arr[n / 2];

    return (arr[(n - 1) / 2] + arr[n / 2]) / 2.0;
}

int main() {
    vector<int> arr = { 1, 3, 4, 2, 7, 5, 8, 6 };
 	double ans = findMedian(arr);
    cout << ans << endl;
    return 0;
}
Java
import java.util.Arrays;

class GfG {
    static double findMedian(int[] arr) {
        int n = arr.length;
      
        // First we sort the array
        Arrays.sort(arr);

        // check for even case
        if (n % 2 != 0)
            return arr[n / 2];

        return (arr[(n - 1) / 2] + arr[n / 2]) / 2.0;
    }

    public static void main(String[] args) {
        int[] arr = { 1, 3, 4, 2, 7, 5, 8, 6 };
        double ans = findMedian(arr);
        System.out.println(ans);
    }
}
Python
def findMedian(arr):
    n = len(arr)
    
    # First we sort the array
    arr.sort()

    # check for even case
    if n % 2 != 0:
        return arr[n // 2]

    return (arr[(n - 1) // 2] + arr[n // 2]) / 2.0

if __name__ == "__main__":
  arr = [1, 3, 4, 2, 7, 5, 8, 6]
  ans = findMedian(arr)
  print(ans)
C#
using System;
using System.Linq;

class GfG {
    static double FindMedian(int[] arr) {
        int n = arr.Length;
        // First we sort the array
        Array.Sort(arr);

        // check for even case
        if (n % 2 != 0)
            return arr[n / 2];

        return (arr[(n - 1) / 2] + arr[n / 2]) / 2.0;
    }

    static void Main() {
        int[] arr = { 1, 3, 4, 2, 7, 5, 8, 6 };
        double ans = FindMedian(arr);
        Console.WriteLine(ans);
    }
}
JavaScript
function findMedian(arr) {
    let n = arr.length;
    
    // First we sort the array
    arr.sort((a, b) => a - b);

    // check for even case
    if (n % 2 !== 0)
        return arr[Math.floor(n / 2)];

	return (arr[Math.floor(n / 2) - 1] + arr[Math.floor(n / 2)]) / 2.0;
}

// Driver Code
let arr = [1, 3, 4, 2, 7, 5, 8, 6];
let ans = findMedian(arr);
console.log(ans);

Output
4.5

Time Complexity: O(n log n) as we need to sort the array first. 
Auxiliary Space: O(1)

[Expected Approach]: Using Randomized QuickSelect  

To find the median of an array, randomly select a pivot element and partition the array using the quicksort technique, placing smaller elements to the left and larger ones to the right. If the pivot lands at the middle index, it is the median. Otherwise, recursively apply this process to the relevant subarray. For even-sized arrays, find the two middle elements and calculate their average.

C++
#include "bits/stdc++.h"
using namespace std;

int partition(vector<int>& arr, int l, int r) {
    int lst = arr[r], i = l, j = l;
    while (j < r) {
        if (arr[j] < lst) {
            swap(arr[i], arr[j]);
            i++;
        }
        j++;
    }
    swap(arr[i], arr[r]);
    return i;
}

int randomPartition(vector<int>& arr, int l, int r){
    int n = r - l + 1;
    int pivot = rand() % n;
    swap(arr[l + pivot], arr[r]);
    return partition(arr, l, r);
}

void medianUtil(vector<int>& arr, int l, int r, int k, int& a, int& b) {
    if (l <= r) {
        int partitionIndex = randomPartition(arr, l, r);

	// find the median of odd number element in arr[]
        if (partitionIndex == k) {
            b = arr[partitionIndex];
            if (a != -1) return;
        }
        // a & b as middle element of arr[]
        else if (partitionIndex == k - 1) {
            a = arr[partitionIndex];
            if (b != -1)  return;
        }
        //  index in first half of the arr[]
        if (partitionIndex >= k)
            return medianUtil(arr, l, partitionIndex - 1, k, a, b);
      
        // find the index in second half of the arr[]
        else
            return medianUtil(arr, partitionIndex + 1, r, k, a, b);
    }
    return;
}

double findMedian(vector<int>& arr) {
    double ans;
  	int  a = -1, b = -1, n = arr.size();

    if (n % 2 == 1) {
        medianUtil(arr, 0, n - 1, n / 2, a, b);
        ans = b;
    } else {
        medianUtil(arr, 0, n - 1, n / 2, a, b);
        ans = (a + b) / 2.0;
    }
   	return ans;
}

int main() {
    vector<int> arr = { 12, 3, 6, 7, 4, 19 };
    cout<<findMedian(arr);
    return 0;
}
Java
import java.util.Random;
import java.util.Arrays;

class GfG {
    static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    public static int partition(int[] arr, int l, int r) {
        int lst = arr[r], i = l, j = l;
        while (j < r) {
            if (arr[j] < lst) {
                swap(arr, i, j);
                i++;
            }
            j++;
        }
        swap(arr, i, r);
        return i;
    }

    public static int randomPartition(int[] arr, int l, int r) {
        Random rand = new Random();
        int n = r - l + 1;
        int pivot = rand.nextInt(n);
        swap(arr, l + pivot, r);
        return partition(arr, l, r);
    }

    public static void medianUtil(int[] arr, int l, int r, int k, int[] a, int[] b) {
        if (l <= r) {
            int partitionIndex = randomPartition(arr, l, r);
            // find the median of odd number element in arr[]
            if (partitionIndex == k) {
                b[0] = arr[partitionIndex];
                if (a[0] != -1) return;
            } else if (partitionIndex == k - 1) { // a & b as middle element of arr[]
                a[0] = arr[partitionIndex];
                if (b[0] != -1) return;
            }
            // index in first half of the arr[]
            if (partitionIndex >= k)
                medianUtil(arr, l, partitionIndex - 1, k, a, b);
            // find the index in second half of the arr[]
            else
                medianUtil(arr, partitionIndex + 1, r, k, a, b);
        }
    }

    public static double findMedian(int[] arr) {
        double ans;
        int[] a = {-1};
        int[] b = {-1};
        int n = arr.length;

        if (n % 2 == 1) {
            medianUtil(arr, 0, n - 1, n / 2, a, b);
            ans = b[0];
        } else {
            medianUtil(arr, 0, n - 1, n / 2, a, b);
            ans = (a[0] + b[0]) / 2.0;
        }
        return ans;
    }

    public static void main(String[] args) {
        int[] arr = {12, 3, 6, 7, 4, 19};
        System.out.println(findMedian(arr));
    }
}
Python
import random

def swap(arr, i, j):
    arr[i], arr[j] = arr[j], arr[i]

def partition(arr, l, r):
    lst = arr[r]
    i = l
    j = l
    while j < r:
        if arr[j] < lst:
            swap(arr, i, j)
            i += 1
        j += 1
    swap(arr, i, r)
    return i

def randomPartition(arr, l, r):
    n = r - l + 1
    pivot = random.randint(0, n - 1)
    swap(arr, l + pivot, r)
    return partition(arr, l, r)

def medianUtil(arr, l, r, k, a, b):
    if l <= r:
        partitionIndex = randomPartition(arr, l, r)
        # find the median of odd number element in arr[]
        if partitionIndex == k:
            b[0] = arr[partitionIndex]
            if a[0] != -1:
                return
        elif partitionIndex == k - 1:  # a & b as middle element of arr[]
            a[0] = arr[partitionIndex]
            if b[0] != -1:
                return
        # index in first half of the arr[]
        if partitionIndex >= k:
            medianUtil(arr, l, partitionIndex - 1, k, a, b)
            
        # find the index in second half of the arr[]
        else:
            medianUtil(arr, partitionIndex + 1, r, k, a, b)

def findMedian(arr):
    a = [-1]
    b = [-1]
    n = len(arr)
    if n % 2 == 1:
        medianUtil(arr, 0, n - 1, n // 2, a, b)
        return b[0]
    else:
        medianUtil(arr, 0, n - 1, n // 2, a, b)
        return (a[0] + b[0]) / 2.0

if __name__ == '__main__':
    arr = [12, 3, 6, 7, 4, 19]
    print(findMedian(arr))
C#
using System;
using System.Linq;

class GfG {
    static void Swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    public static int Partition(int[] arr, int l, int r) {
        int lst = arr[r], i = l, j = l;
        while (j < r) {
            if (arr[j] < lst) {
                Swap(arr, i, j);
                i++;
            }
            j++;
        }
        Swap(arr, i, r);
        return i;
    }

    public static int RandomPartition(int[] arr, int l, int r) {
        Random rand = new Random();
        int n = r - l + 1;
        int pivot = rand.Next(n);
        Swap(arr, l + pivot, r);
        return Partition(arr, l, r);
    }

    public static void MedianUtil(int[] arr, int l, int r, int k, int[] a, int[] b) {
        if (l <= r) {
            int partitionIndex = RandomPartition(arr, l, r);
            // find the median of odd number element in arr[]
            if (partitionIndex == k) {
                b[0] = arr[partitionIndex];
                if (a[0] != -1) return;
            } else if (partitionIndex == k - 1) { // a & b as middle element of arr[]
                a[0] = arr[partitionIndex];
                if (b[0] != -1) return;
            }
            // index in first half of the arr[]
            if (partitionIndex >= k)
                MedianUtil(arr, l, partitionIndex - 1, k, a, b);
            // find the index in second half of the arr[]
            else
                MedianUtil(arr, partitionIndex + 1, r, k, a, b);
        }
    }

    public static double FindMedian(int[] arr) {
        double ans;
        int[] a = {-1};
        int[] b = {-1};
        int n = arr.Length;

        if (n % 2 == 1) {
            MedianUtil(arr, 0, n - 1, n / 2, a, b);
            ans = b[0];
        } else {
            MedianUtil(arr, 0, n - 1, n / 2, a, b);
            ans = (a[0] + b[0]) / 2.0;
        }
        return ans;
    }

    public static void Main(string[] args) {
        int[] arr = {12, 3, 6, 7, 4, 19};
        Console.WriteLine(FindMedian(arr));
    }
}
JavaScript
function swap(arr, i, j) {
    let temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

function partition(arr, l, r) {
    let lst = arr[r];
    let i = l;
    for (let j = l; j < r; j++) {
        if (arr[j] < lst) {
            swap(arr, i, j);
            i++;
        }
    }
    swap(arr, i, r);
    return i;
}

function randomPartition(arr, l, r) {
    let n = r - l + 1;
    let pivot = Math.floor(Math.random() * n);
    swap(arr, l + pivot, r);
    return partition(arr, l, r);
}

function medianUtil(arr, l, r, k, a, b) {
    if (l <= r) {
        let partitionIndex = randomPartition(arr, l, r);
        if (partitionIndex === k) {
            b[0] = arr[partitionIndex];
            if (a[0] !== -1) return;
        } else if (partitionIndex === k - 1) {
            a[0] = arr[partitionIndex];
            if (b[0] !== -1) return;
        }
        if (partitionIndex >= k) {
            medianUtil(arr, l, partitionIndex - 1, k, a, b);
        } else {
            medianUtil(arr, partitionIndex + 1, r, k, a, b);
        }
    }
}

function findMedian(arr) {
    let a = [-1];
    let b = [-1];
    let n = arr.length;
    if (n % 2 === 1) {
        medianUtil(arr, 0, n - 1, Math.floor(n / 2), a, b);
        return b[0];
    } else {
        medianUtil(arr, 0, n - 1, Math.floor(n / 2), a, b);
        return (a[0] + b[0]) / 2.0;
    }
}

// Driver Code
let arr = [12, 3, 6, 7, 4, 19];
console.log(findMedian(arr));

Output
6.5

Time Complexity: 

  1. Best case analysis: O(1)
  2. Average case analysis: O(n)
  3. Worst case analysis: O(n2)

Auxiliary Space: O(n)

[Worst Case Linear Time Approach] - Using Order Statistics

The idea in this new method is similar to quickSelect(). We get worst-case linear time by selecting a pivot that divides the array in a balanced way (there are not very few elements on one side and many on another side). After the array is divided in a balanced way, we apply the same steps as used in quickSelect() to decide whether to go left or right of the pivot. Please refer K’th Smallest/Largest Element in Unsorted Array | Worst case Linear Time for implementation and more details.

Note : Although this approach looks good on paper, the previous quick select approach works better in practice.



Next Article

Similar Reads