Skip to content

Basics

You are given a sorted array AA of length nn. Your goal is to find an element xx in this array. Assume for now that AA consists of distinct elements, and that xx is guranteed to exist in AA.

Here’s how binary search solves this problem. We maintain two variables ll and rr that are initially 00 and n1n-1 respectively. [l,r][l, r] represents the range of indices in AA where xx could lie.

Next, we compute m=l+r2m=\lfloor\frac{l+r}{2}\rfloor. Notice that [l,m][l,m] and [m+1,r][m+1,r] are both roughly half the size of [l,r][l,r]. The key observation to make here is that we can quickly determine if it is impossible for xx to be part of a range. Specifically, if [u,v][u,v] is a range and Au>xA_u>x or Av<xA_v<x, then we know that it’s impossible for xx to be in this range.

We check whether AmA_m is x\ge x. If this is true, we know that xx cannot lie beyond mm, and so must lie in [l,m][l,m]. On the other hand, if this wasn’t true, i.e., Am<xA_m < x, xx would have to lie in [m+1,r][m+1,r].

We can keep dividing our search space in half until it only consists of one index, at which point we will know that Al=Ar=xA_l=A_r=x.

Implementation

Here’s how this is implemented:

int l = 0, r = n - 1;
while (l < r) {
  int m = std::midpoint(l, r);
  if (A[m] >= x) {
    r = m;
  } else {
    l = m + 1;
  }
}
std::cout << x << " is located at index " << l << '\n';

Time complexity: O(logn)\mathcal{O}(\log{n}).

There exists a very popular alternative implementation of binary search that is prefered by some people. Here, the question in hand is a rephrased version of the original one: find the smallest index ii such that AixA_i \ge x (notice that both questions are indeed equivalent).

Alternative implementation
int l = 0, r = n - 1;
int ans = n - 1;
while (l <= r) {
  int m = std::midpoint(l, r);
  if (A[m] >= x) {
    ans = m;
    r = m - 1;
  } else {
    l = m + 1;
  }
}
std::cout << x << " is located at index " << l << '\n';