Skip to content

Discrete Ternary Search

Find the maximum or minimum of a unimodal function defined on discrete indices.

Discrete ternary search finds the maximum or minimum of a unimodal function defined over integer indices. A function is unimodal if it strictly increases up to a point and then strictly decreases, or the reverse.

Unlike binary search, which relies on a monotone predicate, ternary search relies on a unimodal shape.

Problem

Given a function f(i)f(i) defined on integer indices i[0,n1]i \in [0, n-1], find an index ii such that f(i)f(i) is maximum.

Assume:

f(0)f(1)f(k)f(n1) f(0) \le f(1) \le \dots \le f(k) \ge \dots \ge f(n-1)

Key Idea

Divide the interval into three parts using two midpoints:

m1=l+rl3,m2=rrl3 m_1 = l + \frac{r - l}{3}, \quad m_2 = r - \frac{r - l}{3}

Compare f(m1)f(m_1) and f(m2)f(m_2):

  • If f(m1)<f(m2)f(m_1) < f(m_2), the maximum lies in [m1+1,r][m_1 + 1, r]
  • Otherwise, it lies in [l,m21][l, m_2 - 1]

This reduces the search space.

Algorithm

ternary_search_discrete(f, l, r):
    while r - l > 3:
        m1 = l + (r - l) // 3
        m2 = r - (r - l) // 3

        if f(m1) < f(m2):
            l = m1 + 1
        else:
            r = m2 - 1

    best = l
    for i from l to r:
        if f(i) > f(best):
            best = i

    return best

Example

Let

f(i)=(i4)2+10 f(i) = -(i - 4)^2 + 10

The function increases up to i=4i = 4 and decreases afterward.

f(i)=-(i-4)^2+10

The maximum occurs at i=4i = 4.

Correctness

At each step, the algorithm discards one third of the interval while preserving the region containing the maximum.

Because the function is unimodal:

  • If f(m1)<f(m2)f(m_1) < f(m_2), the left third cannot contain the maximum
  • If f(m1)f(m2)f(m_1) \ge f(m_2), the right third cannot contain the maximum

The remaining interval always contains the optimal point.

The final small interval is scanned directly to ensure correctness on discrete indices.

Complexity

phasecost
iterationsO(logn)O(\log n)
final scanO(1)O(1)
totalO(logn)O(\log n)

Each iteration reduces the interval to about two thirds of its size.

Space:

O(1) O(1)

Comparison

methodrequirementtime
binary searchmonotone predicateO(logn)O(\log n)
ternary searchunimodal functionO(logn)O(\log n)

Binary search finds boundaries. Ternary search finds extrema.

When to Use

  • Optimization over discrete domains
  • Peak finding in unimodal arrays
  • Problems where derivative information is unavailable

Notes

  • Final linear scan is necessary because indices are discrete
  • Works for both maximum and minimum with condition reversal

Implementation

def ternary_search_discrete(f, l, r):
    while r - l > 3:
        m1 = l + (r - l) // 3
        m2 = r - (r - l) // 3

        if f(m1) < f(m2):
            l = m1 + 1
        else:
            r = m2 - 1

    best = l
    for i in range(l, r + 1):
        if f(i) > f(best):
            best = i

    return best
func TernarySearchDiscrete(f func(int) int, l, r int) int {
    for r-l > 3 {
        m1 := l + (r-l)/3
        m2 := r - (r-l)/3

        if f(m1) < f(m2) {
            l = m1 + 1
        } else {
            r = m2 - 1
        }
    }

    best := l
    for i := l; i <= r; i++ {
        if f(i) > f(best) {
            best = i
        }
    }

    return best
}