Binary Search finds an element in a sorted array by repeatedly cutting the search range in half — O(log n).
Focus on recognizing:
Sorted + Search → Binary Search
Core Template
public int binarySearch(int[] nums, int target) {
int lo = 0;
int hi = nums.length - 1;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
lo = mid + 1;
} else {
hi = mid - 1;
}
}
return -1;
}def binary_search(nums, target):
lo, hi = 0, len(nums) - 1
while lo <= hi:
mid = lo + (hi - lo) // 2
if nums[mid] == target:
return mid
elif nums[mid] < target:
lo = mid + 1
else:
hi = mid - 1
return -1int binarySearch(vector<int>& nums, int target) {
int lo = 0;
int hi = (int)nums.size() - 1;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
if (nums[mid] == target) return mid;
else if (nums[mid] < target) lo = mid + 1;
else hi = mid - 1;
}
return -1;
}function binarySearch(nums, target) {
let lo = 0,
hi = nums.length - 1;
while (lo <= hi) {
const mid = lo + ((hi - lo) >> 1);
if (nums[mid] === target) return mid;
else if (nums[mid] < target) lo = mid + 1;
else hi = mid - 1;
}
return -1;
}Compare → eliminate half → repeat. Each probe halves the range.
Compare with mid → discard half → repeat.
Pattern 1: First Occurrence
Watch [1,3,5,7,9,11] collapse to three probes to find 7. Press ▶ to animate.
⚠️ Animation & Content Notice
The animation work is not fully finished — some animations may have slight errors.
If there is a major error in the content or if the animation or content is difficult to understand, please contact us at rayyancodingschool@gmail.com.
Classic Binary Search (Iterative)
Find a target in a sorted array by repeatedly halving the search range with lo and hi pointers. O(log n) time, no recursion.
Array [1,3,5,7,9,11], target 7. Compare mid: < target → discard left half (lo=mid+1); > target → discard right half (hi=mid-1); == target → found. The blue excluded region shows what's already thrown away each step.
1
lo = 0, hi = n - 1
2
while lo <= hi:
3
mid = (lo + hi) / 2 // round down
4
if nums[mid] == target: return mid
5
if nums[mid] < target: lo = mid + 1
6
else: hi = mid - 1
7
return -1
1
search(lo, hi):
2
if lo > hi: return -1 // empty range
3
mid = (lo + hi) / 2
4
if nums[mid] == target: return mid
5
if nums[mid] < target:
6
return search(mid + 1, hi)
7
return search(lo, mid - 1)
With duplicates, don’t return immediately — record the match and keep searching left:
public int firstOccurrence(int[] nums, int target) {
int lo = 0;
int hi = nums.length - 1;
int result = -1;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
if (nums[mid] == target) {
result = mid; // candidate
hi = mid - 1; // keep searching left
} else if (nums[mid] < target) {
lo = mid + 1;
} else {
hi = mid - 1;
}
}
return result;
}def first_occurrence(nums, target):
lo, hi = 0, len(nums) - 1
result = -1
while lo <= hi:
mid = lo + (hi - lo) // 2
if nums[mid] == target:
result = mid # candidate
hi = mid - 1 # keep searching left
elif nums[mid] < target:
lo = mid + 1
else:
hi = mid - 1
return resultint firstOccurrence(vector<int>& nums, int target) {
int lo = 0, hi = (int)nums.size() - 1;
int result = -1;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
if (nums[mid] == target) {
result = mid; // candidate
hi = mid - 1; // keep searching left
} else if (nums[mid] < target) {
lo = mid + 1;
} else {
hi = mid - 1;
}
}
return result;
}function firstOccurrence(nums, target) {
let lo = 0,
hi = nums.length - 1,
result = -1;
while (lo <= hi) {
const mid = lo + ((hi - lo) >> 1);
if (nums[mid] === target) {
result = mid; // candidate
hi = mid - 1; // keep searching left
} else if (nums[mid] < target) {
lo = mid + 1;
} else {
hi = mid - 1;
}
}
return result;
}First = Match → Save → Go Left
Pattern 2: Last Occurrence
Mirror image — save and search right:
⚠️ Animation & Content Notice
The animation work is not fully finished — some animations may have slight errors.
If there is a major error in the content or if the animation or content is difficult to understand, please contact us at rayyancodingschool@gmail.com.
Last Occurrence
Find the last occurrence of a target in a sorted array. Bias binary search right on equality — keep searching in the right half.
Array: [1,2,2,2,3], target=2. On match at mid=2, don't stop — search right for a later occurrence. Found at index 3.
1
lo = 0, hi = n - 1, result = -1
2
while lo <= hi:
3
mid = (lo + hi) / 2
4
if nums[mid] == target: result = mid; lo = mid + 1
5
else if nums[mid] < target: lo = mid + 1
6
else: hi = mid - 1
7
return result
public int lastOccurrence(int[] nums, int target) {
int lo = 0;
int hi = nums.length - 1;
int result = -1;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
if (nums[mid] == target) {
result = mid; // candidate
lo = mid + 1; // keep searching right
} else if (nums[mid] < target) {
lo = mid + 1;
} else {
hi = mid - 1;
}
}
return result;
}def last_occurrence(nums, target):
lo, hi = 0, len(nums) - 1
result = -1
while lo <= hi:
mid = lo + (hi - lo) // 2
if nums[mid] == target:
result = mid # candidate
lo = mid + 1 # keep searching right
elif nums[mid] < target:
lo = mid + 1
else:
hi = mid - 1
return resultint lastOccurrence(vector<int>& nums, int target) {
int lo = 0, hi = (int)nums.size() - 1;
int result = -1;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
if (nums[mid] == target) {
result = mid; // candidate
lo = mid + 1; // keep searching right
} else if (nums[mid] < target) {
lo = mid + 1;
} else {
hi = mid - 1;
}
}
return result;
}function lastOccurrence(nums, target) {
let lo = 0,
hi = nums.length - 1,
result = -1;
while (lo <= hi) {
const mid = lo + ((hi - lo) >> 1);
if (nums[mid] === target) {
result = mid; // candidate
lo = mid + 1; // keep searching right
} else if (nums[mid] < target) {
lo = mid + 1;
} else {
hi = mid - 1;
}
}
return result;
}Last = Match → Save → Go Right · For boundaries in general, see Lower & Upper Bound.
Common Mistakes
Integer overflow in mid.
mid = lo + (hi − lo) / 2 — (lo + hi) / 2 can overflow in Java/C++.
Wrong loop condition.
while (lo <= hi) for this template; lo < hi belongs to boundary templates that keep hi = mid.
Returning immediately on duplicates.
First/last occurrence need the save-and-continue dance, not an instant return mid.
Unsorted input.
The halving logic is only valid on a sorted search space.
Complexity
| Operation | Time |
|---|---|
| Search | O(log n) |
| Space | O(1) |
Premium Content
Unlock Classic Binary Search and all premium lessons with a subscription.
From ₹199.99/year — See plans