binary search
algorithm techniques
start vs end condition
programming
computer science

Binary Search using start end vs. using start end

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

The two common binary-search styles differ by the interval they maintain. One style uses an inclusive interval, usually written conceptually as start through end, and loops while start <= end. The other uses a half-open interval, conceptually start through end exclusive, and loops while start < end. Neither style is inherently better, but each has its own invariants and update rules.

Inclusive Interval Style

In the inclusive version, both bounds are candidate positions. That means the search interval is conceptually closed on both ends.

A standard implementation:

python
1def binary_search(nums, target):
2    start = 0
3    end = len(nums) - 1
4
5    while start <= end:
6        mid = start + (end - start) // 2
7
8        if nums[mid] == target:
9            return mid
10        elif nums[mid] < target:
11            start = mid + 1
12        else:
13            end = mid - 1
14
15    return -1

This style is intuitive for exact-element lookup because the loop condition naturally says, “search while there is still at least one candidate element left.”

Half-Open Interval Style

In the half-open version, end is one past the last candidate position. The active interval is conceptually start inclusive and end exclusive.

python
1def binary_search_half_open(nums, target):
2    start = 0
3    end = len(nums)
4
5    while start < end:
6        mid = start + (end - start) // 2
7
8        if nums[mid] < target:
9            start = mid + 1
10        elif nums[mid] > target:
11            end = mid
12        else:
13            return mid
14
15    return -1

Notice the updates:

  • move right with start = mid + 1
  • move left with end = mid

There is no -1 on the left-side update because end is exclusive.

Why the Two Styles Feel Different

The difference is not only the loop condition. It is the interval invariant the code promises to maintain.

Inclusive style invariant:

  • candidates live between start and end, both included

Half-open style invariant:

  • candidates live between start and end, where end itself is not included

Once you pick one invariant, all updates have to match it. Most binary-search bugs happen when code mixes one loop condition with the other style’s update rules.

Half-Open Style Is Good for Boundary Searches

The half-open interval is often convenient for lower-bound and insertion-point problems.

Example: find the first index where nums[index] >= target.

python
1def lower_bound(nums, target):
2    start = 0
3    end = len(nums)
4
5    while start < end:
6        mid = start + (end - start) // 2
7        if nums[mid] < target:
8            start = mid + 1
9        else:
10            end = mid
11
12    return start

This style maps naturally to “search in a prefix of the array” problems because start and end behave like slice boundaries.

Inclusive Style Is Good for Straight Membership Tests

If your goal is simply “find the target or report failure,” many developers find the inclusive version easier to reason about.

That is because the interval directly corresponds to actual valid indices, and the termination condition start > end clearly means “the candidate interval is empty.”

It is a strong default when teaching or writing a one-off exact lookup.

Midpoint Formula Matters Too

No matter which style you choose, compute the midpoint like this:

python
mid = start + (end - start) // 2

In Python, integer overflow is not a practical issue, but this formula is still the standard habit because it carries over safely to languages with fixed-width integers.

The midpoint rule is independent of the inclusive vs half-open interval choice.

Pick One Invariant and Stay Consistent

A useful rule is:

  • inclusive interval: initialize end = len(nums) - 1, loop with <=, update left side with end = mid - 1
  • half-open interval: initialize end = len(nums), loop with <, update left side with end = mid

Once you mix those rules, off-by-one errors appear quickly.

For example, using while start < end together with end = mid - 1 is often a sign that the code is blending incompatible interval models.

Common Pitfalls

The most common mistake is mixing inclusive and half-open update rules in the same implementation. Another is forgetting whether end currently points to a valid candidate index or to one past the valid range. Developers also often use the exact-lookup pattern when they really need a boundary search such as lower bound or first occurrence. A final issue is changing the loop condition without re-deriving the invariant, which turns a once-correct binary search into a subtle off-by-one bug.

Summary

  • 'start <= end usually goes with an inclusive interval.'
  • 'start < end usually goes with a half-open interval.'
  • Neither style is universally better; the important part is internal consistency.
  • Half-open intervals are especially convenient for boundary and insertion-point searches.
  • Most binary-search bugs come from mixing one style’s loop condition with the other style’s updates.

Course illustration
Course illustration

All Rights Reserved.