Skip to content

Lower Median Selection

Select the lower median, the element at index floor((n-1)/2), using selection or partitioning.

Lower Median Selection returns the lower median of a sequence. For even length arrays, there are two central elements. The lower median is the smaller of the two.

This definition is common in discrete settings where a single representative element must be chosen.

Problem

Given an array AA of length nn, return the element with rank:

k=n12 k = \left\lfloor \frac{n - 1}{2} \right\rfloor

That is:

  • for odd nn, the unique median
  • for even nn, the lower of the two middle elements

Algorithm

Use a selection method such as Quickselect or Nth Element.

lower_median(A):
    n = length(A)
    k = (n - 1) // 2
    return quickselect(A, k)

Example

Let:

A=[7,2,9,4] A = [7, 2, 9, 4]

Sorted order:

[2,4,7,9] [2, 4, 7, 9]

The lower median index is:

k=(41)/2=1 k = \lfloor (4 - 1) / 2 \rfloor = 1

So the result is:

4 4

Correctness

The lower median is defined as the element with rank (n1)/2\lfloor (n - 1)/2 \rfloor. Selection algorithms correctly return the element with any specified rank, so applying selection with this index yields the lower median.

Complexity

methodtime
Quickselect averageO(n)O(n)
deterministic selectO(n)O(n)
sortO(nlogn)O(n \log n)

Space:

O(1) O(1)

for in-place selection.

When to Use

Use Lower Median when:

  • you need a stable single representative for even-sized data
  • tie-breaking must favor smaller values
  • deterministic behavior is required in discrete systems

This variant is common in statistics, scheduling, and load balancing.

Implementation

def lower_median(a):
    def quickselect(a, k):
        import random

        left, right = 0, len(a) - 1

        def partition(l, r, p):
            pivot = a[p]
            a[p], a[r] = a[r], a[p]
            store = l
            for i in range(l, r):
                if a[i] < pivot:
                    a[store], a[i] = a[i], a[store]
                    store += 1
            a[r], a[store] = a[store], a[r]
            return store

        while True:
            if left == right:
                return a[left]

            p = random.randint(left, right)
            p = partition(left, right, p)

            if k == p:
                return a[k]
            elif k < p:
                right = p - 1
            else:
                left = p + 1

    k = (len(a) - 1) // 2
    return quickselect(a, k)
func LowerMedian(a []int) int {
	k := (len(a) - 1) / 2
	return Quickselect(a, k)
}