Skip to main content

Searching: Linear and Binary

intermediate25 min readLesson 123 of 204

std::find vs binary_search/lower_bound, the sorted-data requirement, and why hand-rolled binary search is a rite of passage.

Linear search is std::find โ€” O(n), works on anything with equality. Binary search is different: it requires sorted data and random access, and pays back with O(log n).

#include <algorithm>
#include <vector>

std::vector<int> v{1, 3, 5, 7, 9, 11};

bool has = std::binary_search(v.begin(), v.end(), 7);      // yes/no

auto lb = std::lower_bound(v.begin(), v.end(), 7);  // first >= 7
auto ub = std::upper_bound(v.begin(), v.end(), 7);  // first > 7

lower_bound/upper_bound are the workhorses: lower_bound gives the first position where the value could be inserted keeping order; upper_bound gives the last. The distance between them is the count of equal elements. On std::map/std::set, the same-named members do this in O(log n) without touching iterators.

The classic beginner bug: binary searching unsorted data. It silently returns wrong answers โ€” no exception, no warning. Sort first, or use a structure that keeps itself sorted.

Implementing your own binary search is a rite of passage precisely because the boundary arithmetic (lo + (hi - lo) / 2, lo <= hi vs lo < hi) has consumed generations of programmers. The standard library versions already survived that fight โ€” prefer them.

Now practice

Algorithm practiceHand-rolled binary search and the one-pass two-sum.2 challenges ยท ยท ~35 min