Problem Statement

Two runners are racing to a finish line at position . Runner A starts at position 0; runner B has a head start at position (e.g. ). It is given that A wins the race in seconds. You are given each runner’s position at every second of the race, as two arrays: Find an index where A “passes” B — that is, and .


Problem Specification

  • Input: Two arrays and such that , , and .
  • Output: An index such that and (the “turning point”).
  • Constraints: ; positions are given for every integer second through .
  • Assumptions: A starts behind or tied with B () and finishes strictly ahead (), so a turning point is guaranteed to exist (discrete Intermediate Value Theorem).
  • Edge cases to consider: (only one possible turning point, ); A passes B exactly once vs. multiple times (algorithm only guarantees finding one valid , not necessarily the first).

Core Logic / Strategy / Approach

  1. Maintain two pointers lo and hi such that the invariant and always holds.
  2. At each step, probe the midpoint m between lo and hi.
  3. If m itself is the turning point ( and ), return it immediately.
  4. Otherwise, use the sign of the comparison at m (and m+1) to discard half the search space — shrinking the range [lo, hi] while preserving the invariant.
  5. Repeat until lo and hi are adjacent (lo + 1 = hi), at which point they must be the turning point by the invariant.

Key Idea

The condition "" transitions to "" exactly once as we sweep left to right in the sense that matters here: at any index lo with and any index hi with , there is guaranteed to be a turning point somewhere in . This lets us binary search on the comparison sign the same way we’d binary search on a monotonic predicate, even though and themselves need not be monotonic.


Solution in Pseudocode

Algorithm 13 Two Runners

Input: Two lists A[0n]A[0 \dots n] and B[0n]B[0 \dots n] such that A[0]=0A[0] = 0, A[0]B[0]A[0] \leq B[0] and A[n]>B[n]A[n] > B[n]

Output: Index jj such that A[j]B[j]A[j] \leq B[j] and A[j+1]>B[j+1]A[j+1] > B[j+1]

procedure TwoRunners(A[0n],B[0n]A[0 \dots n], B[0 \dots n])

lo=0lo = 0

hi=nhi = n

while lo+1<hilo + 1 < hi do

m=lo+hi2m = \lfloor \frac{lo + hi}{2} \rfloor

if A[m]B[m]A[m] \leq B[m] and A[m+1]>B[m+1]A[m+1] > B[m+1] then

return mm

if A[m]>B[m]A[m] > B[m] then

hi=mhi = m

if A[m+1]B[m+1]A[m + 1] \leq B[m+1] then

lo=m+1lo = m + 1

return lolo

Variables & Data Structures

NameTypePurpose
loIndex (integer)Left boundary of search range; always satisfies
hiIndex (integer)Right boundary of search range; always satisfies
mIndex (integer)Midpoint probe,

Helper Functions / Operations Used

  • Array indexing A[i], B[i] random access into the given arrays.
  • Comparison A[i] \le B[i] per check.
  • No auxiliary data structures are needed; the algorithm operates entirely on the two input arrays with two integer pointers.

Proof of Correctness

Claim: Upon termination, the algorithm returns an index such that and .

Loop Invariant: After every iteration (and before the loop begins), and .

  • Initialization: Before the loop, and . By the given parameters, and , so the invariant holds trivially at the start.
  • Maintenance: Suppose the invariant holds before an iteration, i.e. and . Consider the midpoint :
    • If and , the algorithm has found the turning point directly and terminates, returning — correctness holds immediately.
    • If , the algorithm sets . By the inductive hypothesis is unaffected, and the new satisfies since by assumption. Invariant preserved.
    • If , the algorithm sets . By the inductive hypothesis is unaffected, and the new satisfies since by assumption. Invariant preserved.
    • These two update branches aren’t mutually exclusive, but at least one always fires whenever the direct-return condition fails: failing to return means NOT( and ), which by De Morgan’s means either or holds — guaranteeing at least one branch executes and the range strictly shrinks.
  • Termination: The loop condition is , and each iteration either returns directly or strictly shrinks the range (since moves up to or moves down to ). So the loop must eventually reach and exit. At that point, by the invariant, and — exactly the turning-point condition — so returning is correct.

Time & Space Complexity Analysis

General Case

ComplexityNotes
TimeEach iteration does work and halves the range :
SpaceOnly a constant number of index variables (lo, hi, m) are used beyond the input arrays

Implementation-Dependent Variations

Data Structure ChoiceImpact on TimeImpact on SpaceNotes
Arrays (given) random access per comparison auxiliaryAssumed representation; enables the binary search
Linked lists instead of arrays to reach m per iteration auxiliaryWould degrade total time to or worse — binary search needs random access
Linear scan (brute force) alternativeSimpler but asymptotically much slower for large

Best / Worst / Average Case

  • Best case: — the very first midpoint checked happens to be the turning point.
  • Worst case: — the search range must be halved all the way down to a single adjacent pair (lo, hi).
  • Average case: — binary search’s halving behavior means the average case matches the worst case asymptotically.

Drawbacks / Constraints

  • Preconditions: Requires and to guarantee a turning point exists; requires random-access (array-like) input.
  • Fails / degrades when: The “at least one boundary condition holds” property between comparisons doesn’t extend to guaranteeing a unique turning point — if A passes and re-passes B multiple times, the algorithm returns some valid turning point, not necessarily the first or last.
  • Not suitable for: Finding all turning points (would need a full scan, ) or finding a specific one (e.g., “first” or “last”) without additional constraints.
  • Alternatives to consider: A linear scan trivially finds the first turning point in if that specific guarantee is required.

References / Links