DSA sheet · Binary Search · Classic binary search pattern

Binary Search Basics

This is the first question of the classic binary search pattern: LeetCode 704, "Binary Search". Find a target in a sorted array and return its index, or −1. The teacher first shows the obvious linear search, then explains, with an everyday example from school, why a sorted array lets us do much better. Then she builds binary search step by step: why we look at the middle, why we move to mid + 1 / mid - 1, why we check "equal" first, and why the loop is while left <= right.

Why it matters: every later binary search problem is this loop with small changes. If these four decisions are clear, the rest of the sheet is much easier.

Every part below follows the same order:
① the question in simple words → ② what the constraints tell us → ③ intuition → ④ building the conditions from examples → ⑤ approach steps → ⑥ code → ⑦ code line by line → ⑧ dry run → ⑨ complexity & remember

Part 0 · Before starting

Words we will use

Why binary search works here

Because the array is sorted, one comparison at mid tells us which side can't contain the target. If nums[mid] is smaller than the target, everything left of mid is even smaller, so we can drop all of it. If it's bigger, everything right of mid is even bigger, so we drop that. Each comparison throws away half.

The mid formula

In this video the teacher writes mid = (left + right) / 2, because the constraints are small (n ≤ 10⁴). The safer form she uses from the next video on is mid = left + (right - left) // 2. They give the same index. The second one never adds two big numbers, so in Java/C++ it can't go past the int limit (2³¹ − 1) and wrap to a negative number (overflow). Python ints never overflow, so both are safe in Python. We use the safe form anyway, as a habit.


Part A · Linear search (the simple way)

LeetCode 704

1The question in simple words

You get an array nums of integers, sorted in ascending order, and an integer target. If the target is in the array, return its index. If not, return −1 (which means "not found").

index012345
value-1035912

target = 9 → answer 4. target = 2 → answer −1.

2What the constraints tell us

3Intuition

The teacher says there are two kinds of searching: linear and binary. Linear is the obvious one: start at index 0 and look at every item one by one until you find the target or reach the end. Since all we have to do is find one value, this is a valid answer.

4Building the logic

Doubt: linear search works on any array. Why is it "lengthy"?
→ In the worst case (target at the end, or missing), it looks at all n items: O(n). It doesn't use the fact that the array is sorted at all. Binary search does, and that's where the speed comes from.

5Approach steps

  1. For i from 0 to n−1: if nums[i] == target, return i.
  2. After the loop, return −1.

6Code (Python)

Binary Search problem, linear search
class SolutionLinear:
    def search(self, nums, target):
        for i in range(len(nums)):
            if nums[i] == target:
                return i        # found it
        return -1               # checked everything, not there

7Code line by line

linewhat it means
for i in range(len(nums)):Visit indexes 0, 1, 2, … one at a time.
if nums[i] == target: return iThis is the target, so return where it is.
return -1We only get here if no index matched.

8Dry run

target 9 in [-1, 0, 3, 5, 9, 12]: check −1 ✗, 0 ✗, 3 ✗, 5 ✗, 9 ✓ → return 4. That's 5 looks. For target 20, we'd check all 6 and return −1.

9Complexity & remember

Remember linear searchCorrect and simple, O(n). It ignores the sorted order, which is the clue for something faster.

Part B · Binary search (the optimal way)

1The question

Same question. Now we use the sorted order to bring the time down from O(n) to O(log n).

2What the constraints tell us

Same as Part A. n ≤ 10⁴, so linear would pass too, but binary search is what the problem is testing. The values and indexes are small, so left + right can't overflow even in Java. That's why the teacher uses the simple (left + right) / 2 in this video. We still write the safe form.

3Intuition: we already do this in daily life

The teacher's example: in school, for the morning assembly, students stand in a line sorted by height. If a teacher is looking for a student she knows is short, she doesn't start from the tall end of the line. She goes straight to the short end. Without calling it that, she's using the sorted order to skip most of the line. That's the spirit of binary search.

Now in an array. Suppose we're looking for 9, and we happen to land on 3.

The rule: pick a point, compare it with the target, and drop the side that can't contain it. Smaller than the target → drop the left, go right. Bigger → drop the right, go left.

4Building the conditions from examples

Which point do we pick? Always the middle

We can't pick at random. A random pick might be near one end and drop only a tiny piece. So by definition we always compare with the middle of the current range. Whatever the comparison says, half the range goes away.

First decide the range: from index 0 (left) to index n − 1 (right). In our array that's 0 to 5 (length 6). Middle = (0 + 5) / 2 = 2.5 → 2 (we drop the decimal). nums[2] = 3.

index012345
value-1035912left 0, right 5, mid 2

mid is smaller than the target → left = mid + 1

3 < 9, so 9 must be on the right. We move the left pointer forward. To where? To mid + 1, not mid.

Doubt 1: why mid + 1 and not mid?
→ We just checked mid: its value (3) is smaller than the target, so mid itself is not the answer either. There's no reason to keep it in the range. Start right after it.
value-1035912left 3, right 5, mid (3 + 5) / 2 = 4

mid equals the target → return mid (check this first)

The new range is 3 … 5. Middle = 4, nums[4] = 9. Here we don't need "less than" or "greater than". We just check whether they're equal. They are, so there's nothing left to search: return index 4.

That's why, in the code, the equal check comes before the less-than check: if we've found it, we stop right away.

mid is bigger than the target → right = mid - 1

Suppose instead mid had landed on 12 while we search for 9. Everything from 12 onward is too big, so the answer must be to the left. Move the right pointer back. To mid or mid − 1?

Doubt 2: why mid - 1?
→ Same reason as before: mid's value didn't match, so why keep it in the range for no reason? End the range just before it.

When does the loop stop? while left <= right

The left pointer only moves right, and the right pointer only moves left. So at some point they meet, and then cross. Once they've crossed, the range is empty and there's nothing more to search. So we keep looping only while left <= right.

Doubt 3: why <= and not <?
→ When left == right, there's still one index left that we haven't checked. With < the loop would stop before looking at it. Example: [5], target 5. left = right = 0. With < we'd never enter the loop and wrongly return −1.

The target is missing → return −1 after the loop

The teacher's example: search for 20 in the same array.

If the target is found, the return inside the loop ends the function, and the final return -1 never runs. If that last line does run, it means we never found the target.

5Approach steps

  1. left = 0, right = len(nums) - 1.
  2. While left <= right: mid = left + (right - left) // 2.
  3. If nums[mid] == target → return mid.
  4. Else if nums[mid] < target → left = mid + 1 (go right).
  5. Else → right = mid - 1 (go left).
  6. After the loop → return −1.

6Code (Python)

Binary Search problem, binary search
class Solution:
    def search(self, nums, target):
        left = 0
        right = len(nums) - 1
        while left <= right:
            mid = left + (right - left) // 2
            if nums[mid] == target:
                return mid              # found
            elif nums[mid] < target:
                left = mid + 1          # target is on the right
            else:
                right = mid - 1         # target is on the left
        return -1                       # pointers crossed: not present

7Code line by line

linewhat it means
left = 0 right = len(nums) - 1The search range starts as the whole array: first index to last index.
while left <= right:While at least one index is still in the range (including the case of exactly one).
mid = left + (right - left) // 2The middle of the current range. Same as (left + right) // 2, but overflow-safe in other languages.
if nums[mid] == target: return midChecked first: if mid is the target, we're done.
elif nums[mid] < target: left = mid + 1mid and everything to its left are too small. Keep only the right part.
else: right = mid - 1mid and everything to its right are too big. Keep only the left part.
return -1Only reached when left passed right, which means the target isn't there.

8Dry run

Found: target 9

stepleftrightmidnums[mid]decisionwhat we throw away
105233 < 9 → left = 3−1, 0, 3
23549equal → return 4—

Not found, bigger than everything: target 20

stepleftrightmidnums[mid]decisionwhat we throw away
105233 < 20 → left = 3−1, 0, 3
235499 < 20 → left = 55, 9
35551212 < 20 → left = 612
end65left > right → loop stops → return −1
step 1-1035912
step 2-1035912
step 3-1035912left = right = 5
end-1035912everything thrown away → −1

Not found, in the middle: target 2

stepleftrightmidnums[mid]decision
105233 > 2 → right = 1
2010−1−1 < 2 → left = 1
311100 < 2 → left = 2
end21crossed → return −1

9Complexity & remember

Every comparison sends us either left or right, so half of the range is ignored. After 1 step n/2 items are left, after 2 steps n/4, then n/8, and so on, until 1 is left. The number of steps k satisfies n / 2k = 1, so k = log₂ n.

nlinear (worst)binary (worst)
6 (our array)63
10⁴ (the max here)10,00014
10⁹10⁹ → TLE30
Remember the template left = 0, right = n−1 · while left <= right · mid · equal → return · smaller → left = mid + 1 · bigger → right = mid − 1 · after the loop → −1.

The teacher ends with a reminder: binary search isn't only about finding an index in an array. Coming next in the sheet: rotated arrays, lower bound, binary search on the answer, and binary search on a 2D matrix.


Part C · Revision page

linear searchbinary search
needs sorted input?noyes
how it movesone index at a timejumps to the middle, drops half
timeO(n)O(log n)
spaceO(1)O(1)
compare nums[mid] with targetactionwhy
equalreturn midfound, stop now
smallerleft = mid + 1mid and its left side are all too small
biggerright = mid - 1mid and its right side are all too big
loop ends (left > right)return −1the range is empty
If you remember only 5 lines 1. Sorted array → think binary search.
2. Always compare with the middle so each step drops half.
3. Check equal first, then move mid + 1 or mid - 1 (mid is never the answer after a mismatch).
4. Loop while left <= right, because one index can still be left when they're equal.
5. n → n/2 → n/4 → … → 1 is log₂ n steps.
Mistakes to avoid ✗ left = mid / right = mid here (can loop forever)
✗ while left < right (misses the last single index)
✗ right = len(nums) instead of len(nums) - 1 (can read past the end)
✗ returning −1 inside the loop on the first mismatch
test it yourself (paste under the solutions above)
s = Solution()
print(s.search([-1, 0, 3, 5, 9, 12], 9))    # 4
print(s.search([-1, 0, 3, 5, 9, 12], 20))   # -1
print(s.search([-1, 0, 3, 5, 9, 12], 2))    # -1
print(s.search([5], 5))                     # 0
print(SolutionLinear().search([-1, 0, 3, 5, 9, 12], 9))   # 4

Based on this video: Binary Search | Classic Binary Search pattern