Master this topic with zero to advance depth.
is the gold standard for searching in massive datasets. Instead of looking at every element, we discard half the possibilities at every step.
For Binary Search to work, the search space must be Monotonic. This usually means:
| Pillar | Detail | Why? |
|---|---|---|
| Search Space | The range of possible answers. | Defines where to hunt. |
| Mid Point | Prevents integer overflow. | |
| Decision Logic | Determining if we should look in the left half or right half. | Discards elements. |
while (low <= high), Update: low = mid + 1 or high = mid - 1.while (low < high), Update: high = mid to keep candidate.if (possible(X)) high = mid.If you're looking for "Pallav" in a phone book, you don't start at page 1. You open the middle, see "M", realize "P" is later, and discard everything before "M". You repeat this until you land on the page.
Binary Search
Given a sorted array of integers nums and a target value target, return the index of target if it exists. Otherwise, return -1. You must write an algorithm with runtime complexity.
Examples
9 exists at index 4.
2 does not exist in the array.
Intuition
The most basic way to find a target is to check every element one by one. While simple, it fails to exploit the 'sorted' property of the input.
Detailed Dry Run
| Step | Index | Value | Match? |
|---|---|---|---|
| 1 | 0 | -1 | No |
| 2 | 1 | 0 | No |
| 3 | 2 | 3 | No |
| 4 | 3 | 5 | No |
| 5 | 4 | 9 | Yes (Return 4) |
Intuition
Binary search naturally follows a 'Divide and Conquer' pattern. We check the middle, and then solve the same problem on a smaller subarray (either left or right half).
Detailed Dry Run
Target: 9, Range: [0, 5]
mid = 2 (val 3). 3 < 9. Recurse right half [3, 5].mid = 4 (val 9). 9 == 9. Return 4.Intuition
Iterative binary search is the industry standard. It achieves the same time but uses constant space by avoiding recursion. Key point: Always use mid = l + (r - l) / 2 to avoid integer overflow.
Detailed Dry Run
| Step | L | R | Mid | nums[Mid] | Decision |
|---|---|---|---|---|---|
| 1 | 0 | 5 | 2 | 3 | 3 < 9 → L = 3 |
| 2 | 3 | 5 | 4 | 9 | 9 == 9 → Return 4 |
Search Insert Position
Given a sorted array of distinct integers nums and a target value target, return the index if the target is found. If not, return the index where it would be if it were inserted in order. Your algorithm must run in time.
Examples
Intuition
Since the array is sorted, we can simply find the first element that is greater than or equal to the target. That index is our insertion point.
Detailed Dry Run
nums = [1,3,5,6], target = 2
Intuition
Binary search finds the 'lower bound'—the first index where nums[index] >= target. When the loop while (l <= r) exits, the l pointer naturally lands on the correct insertion index.
Detailed Dry Run
| Step | L | R | Mid | nums[Mid] | Decision |
|---|---|---|---|---|---|
| 1 | 0 | 3 | 1 | 3 | 3 > 2 → R = 0 |
| 2 | 0 | 0 | 0 | 1 | 1 < 2 → L = 1 |
| Exit | 1 | 0 | - | - | Return L = 1 |
Find First and Last Position of Element in Sorted Array
Given an array of integers nums sorted in non-decreasing order, find the starting and ending position of a given target value. If target is not found in the array, return [-1, -1]. You must write an algorithm with runtime complexity.
Examples
Intuition
Scan from the left to find the first occurrence, and from the right to find the last. While simple, it takes time, missing the efficiency of sorted bounds.
Detailed Dry Run
nums = [5,7,7,8,8,10], target = 8
Intuition
Most languages provide built-in binary search functions (like bisect_left and bisect_right in Python, or lower_bound/upper_bound in C++). These are highly optimized and should be used in production.
Detailed Dry Run
nums = [5,7,7,8,8,10], target = 8
lower_bound finds first index where val >= 8: index 3.upper_bound finds first index where val > 8: index 5.Intuition
We perform two separate binary searches. In the first search (find left bound), when nums[mid] == target, we continue searching left (high = mid - 1). In the second search (find right bound), we continue searching right (low = mid + 1).
Detailed Dry Run
nums = [5,7,7,8,8,10], target = 8
mid = 2 (val 7). 7 < 8 -> L=3. mid = 4 (val 8). 8==8 -> save 4, R=3. mid = 3 (val 8). 8==8 -> save 3, R=2. End. Result index 3.Find Peak Element
A peak element is an element that is strictly greater than its neighbors. Given an integer array nums, find a peak element, and return its index. If the array contains multiple peaks, return the index to any of the peaks. You may imagine that nums[-1] = nums[n] = -\\infty. You must write an algorithm that runs in time.
Examples
3 is a peak element and its index is 2.
Your function can return either index 1 where the peak element is 2, or index 5 where the peak element is 6.
Intuition
Since any element that is greater than its next neighbor is a potential peak (because we know the previous element was smaller, or it's the first element), we can just scan linearly.
Detailed Dry Run
nums = [1,2,3,1]
Intuition
Divide the array and check the middle element's slope. If we are going up, a peak must exist on the right. If we are going down, a peak must exist on the left.
Detailed Dry Run
nums = [1,2,3,1]. L=0, R=3.
Intuition
We can use binary search by looking at the slope. If nums[mid] < nums[mid+1], it means we are on a rising slope, and a peak must exist to the right. If nums[mid] > nums[mid+1], we are on a falling slope, and a peak must exist to the left (including mid).
Detailed Dry Run
| Step | L | R | Mid | nums[Mid] | nums[Mid+1] | Decision |
|---|---|---|---|---|---|---|
| 1 | 0 | 6 | 3 | 3 | 5 | 3 < 5 → L = 4 |
| 2 | 4 | 6 | 5 | 6 | 4 | 6 > 4 → R = 5 |
| 3 | 4 | 5 | 4 | 5 | 6 | 5 < 6 → L = 5 |
| Exit | 5 | 5 | - | - | - | Return L = 5 |
Find Minimum in Rotated Sorted Array
Suppose an array of length n sorted in ascending order is rotated between 1 and n times. Given the sorted rotated array nums of unique elements, return the minimum element of this array. You must write an algorithm that runs in time.
Examples
The original array was [1,2,3,4,5] rotated 3 times.
The original array was [0,1,2,4,5,6,7] and it was rotated 4 times.
Intuition
Simply scan the array and find the minimum element. We don't exploit the sorted/rotated property.
Detailed Dry Run
nums = [3,4,5,1,2]. Min starts at 3. Compare with 4, 5, 1 (new min), 2. Result: 1.
Intuition
In a rotated sorted array, if nums[mid] > nums[right], the minimum must be in the right half (excluding mid). Otherwise, it's in the left half (including mid).
Detailed Dry Run
| Step | L | R | Mid | nums[Mid] | nums[R] | Decision |
|---|---|---|---|---|---|---|
| 1 | 0 | 4 | 2 | 5 | 2 | 5 > 2 → L = 3 |
| 2 | 3 | 4 | 3 | 1 | 2 | 1 < 2 → R = 3 |
| Exit | 3 | 3 | - | - | - | Return nums[3] = 1 |
Search in Rotated Sorted Array
Given the array nums after a possible rotation and an integer target, return the index of target if it is in nums, or -1 if it is not in nums. All values in nums are unique. You must write an algorithm that runs in time.
Examples
Intuition
The simplest way is to iterate through the entire array and check if any element equals the target.
Detailed Dry Run
nums = [4,5,6,7,0,1,2], target = 0
Intuition
First, find the index of the minimum element (the pivot). This splits the array into two sorted halves. Perform a standard binary search on the appropriate half.
Detailed Dry Run
nums = [4,5,6,7,0,1,2], target = 0
Intuition
In every step, at least one half of the current range must be sorted. We check which half is sorted and determine if the target lies within it. This avoids finding the pivot separately.
Detailed Dry Run
| Step | L | R | Mid | nums[Mid] | Sorted? | Target In? | Decision |
|---|---|---|---|---|---|---|---|
| 1 | 0 | 6 | 3 | 7 | Left [0..3] | No (0 < 4 or 0 > 7) | L = 4 |
| 2 | 4 | 6 | 5 | 1 | Right [5..6] | No (0 < 1 or 0 > 2) | R = 4 |
| 3 | 4 | 4 | 4 | 0 | Found! | - | Return 4 |
Search a 2D Matrix
Write an efficient algorithm that searches for a value target in an m x n integer matrix matrix. The matrix has the following properties: Each row is sorted in non-decreasing order. The first integer of each row is greater than the last integer of the previous row.
Examples
Intuition
Iterate through every row and every column to find the target. This does not take advantage of any sorting.
Detailed Dry Run
Searching for 3 in [[1,3,5...], ...]
Intuition
First, binary search through the first column to find which row could potentially contain the target. Then, perform a binary search within that specific row.
Detailed Dry Run
matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
Intuition
Treat the entire matrix as a single sorted array of size . We can map a 1D index idx to 2D coordinates using row = idx / n and col = idx % n.
Detailed Dry Run
| Step | L | R | Mid | Row=Mid/4 | Col=Mid%4 | Val | Decision |
|---|---|---|---|---|---|---|---|
| 1 | 0 | 11 | 5 | 1 | 1 | 11 | 11 > 3 → R = 4 |
| 2 | 0 | 4 | 2 | 0 | 2 | 5 | 5 > 3 → R = 1 |
| 3 | 0 | 1 | 0 | 0 | 0 | 1 | 1 < 3 → L = 1 |
| 4 | 1 | 1 | 1 | 0 | 1 | 3 | Found! |
Single Element in a Sorted Array
You are given a sorted array consisting of only integers where every element appears exactly twice, except for one element which appears exactly once. Find this single element that appears only once. Your solution must run in time and space.
Examples
Intuition
XORing a number with itself results in 0. XORing 0 with any number results in that number. If we XOR all elements, the pairs will cancel out, leaving the single element.
Detailed Dry Run
nums = [1,1,2] 1 ^ 1 ^ 2 = 0 ^ 2 = 2. Result: 2.
Intuition
Since the array is sorted, we can check elements in pairs. If nums[i] is not equal to nums[i+1], then nums[i] is the single element.
Detailed Dry Run
nums = [1,1,2,3,3]
Intuition
In a paired array, pairs start at even indices: (0,1), (2,3), etc. Before the single element, nums[even] == nums[even+1]. After the single element, this pattern breaks. We search for the first index where nums[even] != nums[even+1].
Detailed Dry Run
| Step | L | R | Mid | Mid_Even | nums[M_E] == nums[M_E+1] | Decision |
|---|---|---|---|---|---|---|
| 1 | 0 | 8 | 4 | 4 | 3 == 4 (No) | R = 4 |
| 2 | 0 | 4 | 2 | 2 | 2 == 3 (No) | R = 2 |
| Exit | 2 | 2 | - | - | - | Return nums[2] = 2 |
Find K Closest Elements
Given a sorted integer array arr, two integers k and x, return the k closest integers to x in the array. The result should also be sorted in ascending order.
Examples
Intuition
Calculate the absolute difference of each element from . Sort the array based on these distances. In case of a tie, the smaller element comes first. Return the first elements.
Detailed Dry Run
arr = [1,2,3,4,5], k = 4, x = 3
Intuition
Use binary search to find the position closest to . Then expand outwards using two pointers to find the closest elements.
Detailed Dry Run
arr = [1,2,3,4,5], k=4, x=3
Intuition
We want a contiguous window of k elements from the sorted array. Binary search for the LEFT endpoint of that window. For a candidate window starting at mid, compare if x - arr[mid] (distance to left edge) is greater than arr[mid+k] - x (distance to right edge). If left edge is farther, shift window right.
Detailed Dry Run
Input: arr=[1,2,3,4,5], k=4, x=3
| Step | l | r | mid | arr[mid] | arr[mid+k] | dist left | dist right | Decision |
| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |
| 1 | 0 | 1 | 0 | 1 | 5 | 3-1=2 | 5-3=2 | Equal, go left: r=0 |
| l==r==0 → window=[arr[0]..arr[3]]=[1,2,3,4]** |
⚠️ Common Pitfalls & Tips
The search bounds are [0, N-K] (not [0, N-1]). The tie-breaking rule is: when x - arr[mid] == arr[mid+k] - x, prefer the smaller element (i.e., r = mid, not l = mid+1).
Capacity To Ship Packages Within D Days
A conveyor belt has packages that must be shipped from one port to another within days days. The i-th package on the conveyor belt has a weight of weights[i]. Find the least weight capacity of the ship that will result in all the packages on the conveyor belt being shipped within days days.
Examples
Intuition
The minimum possible capacity is max(weights) (must ship heaviest package) and maximum is sum(weights) (all in one day). Try each value from min ascending and try to simulate — find the first one that ships all packages within D days.
Detailed Dry Run
Input: weights=[1,2,3,4,5,6,7,8,9,10], days=5
Min capacity = max = 10. Try 10: simulate → days used = 10 (too many). Try 15: simulate [1-5=15], [6-8=21 split], check... Actually enumerate until 15 fits in 5 days.
⚠️ Common Pitfalls & Tips
This tries every integer from max to sum. It's TLE for large inputs. Binary Search on Answer reduces this from O(Sum) iterations to O(log(Sum)) iterations.
Intuition
Wrap the binary search logic in a recursive function. The search space is still the same: [max(weights), sum(weights)].
Detailed Dry Run
lo=10, hi=55. mid=32. feasible? Yes. Recurse [10, 32].
Intuition
The answer (minimum capacity) lies in the range [max(weights), sum(weights)]. This range is MONOTONE: if capacity C works, C+1 also works. If capacity C doesn't work, C-1 doesn't either. This is the 'feasibility check + binary search' pattern — search for the LEFT boundary of feasible capacities.
Detailed Dry Run
weights=[1,2,3,4,5,6,7,8,9,10], days=5. Range: lo=10, hi=55
| Step | lo | hi | mid | simulate(mid) | days needed | <=5? | Action |
|---|---|---|---|---|---|---|---|
| 1 | 10 | 55 | 32 | [1..6]=21,[7,8]=15,[9]=9,[10]=10 | 4 | Yes | hi=32 |
| 2 | 10 | 32 | 21 | [1..6]=21,[7,8]=15,[9,10]=19 | 3 | Yes | hi=21 |
| 3 | 10 | 21 | 15 | [1-5]=15,[6-8]=21 wait 21>15, split... | 5 | Yes | hi=15 |
| 4 | 10 | 15 | 12 | [1-5]=15? 15>12, split... | 6 | No | lo=13 |
| 5 | 13 | 15 | 14 | simulate → 5 days | Yes | hi=14 | |
| 6 | 13 | 14 | 13 | simulate → 6 | No | lo=14 | |
| lo==hi==15... → return 15 |
⚠️ Common Pitfalls & Tips
The search range is [max(weights), sum(weights)]. Use lo < hi (not <=). When feasible, set hi = mid (not mid-1) to keep candidate in range. The feasibility function simulates greedy packing: always add to current day until capacity exceeded, then start new day.
Split Array Largest Sum
Given an integer array nums and an integer k, split the array into k non-empty contiguous subarrays such that the largest sum of any subarray is minimized. Return the minimized largest sum of the split.
Examples
Intuition
Try all possible ways to split the array using recursion with memoization. dp[i][j] represents the minimum largest sum for the subarray nums[i:] split into j parts.
Detailed Dry Run
nums = [7,2,5], k=2
Intuition
The minimum largest sum ranges from max(nums) to sum(nums). This range is monotonic: if a max-sum is feasible with splits, is also feasible. We binary search for the smallest .
Detailed Dry Run
| Step | L | R | Mid | Count | Decision |
|---|---|---|---|---|---|
| 1 | 10 | 32 | 21 | 2 | R = 21 |
| 2 | 10 | 21 | 15 | 3 | L = 16 |
| 3 | 16 | 21 | 18 | 2 | R = 18 |
| Exit | - | - | - | - | Return 18 |
Median of Two Sorted Arrays
Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays. The overall run time complexity should be .
Examples
Intuition
Use the merge step of merge sort to combine the two arrays into one sorted array. Then find the middle element(s).
Detailed Dry Run
nums1 = [1,3], nums2 = [2] Merged: [1,2,3]. n=3. Median: Index 1 (Value 2).
Intuition
Find the -th smallest element in two sorted arrays by comparing the middle elements of each array (divided by 2 at each step).
Detailed Dry Run
Find 5th element in [1,3,5,...] and [2,4,6,...]. Compare 2nd elements...
Intuition
We can binary search for the correct partition point in the smaller array. A partition is correct if all elements on the left side are smaller than all elements on the right side.
Detailed Dry Run
nums1 = [1,3], nums2 = [2]
Find K-th Smallest Pair Distance
The distance of a pair of integers a and b is defined as the absolute difference between a and b. Given an integer array nums and an integer k, return the k-th smallest distance among all the pairs nums[i] and nums[j] where .
Examples
Intuition
Calculate every possible pair distance, store them, and pick the -th smallest.
Detailed Dry Run
nums = [1,3,1], k=1 Distances: |1-3|=2, |1-1|=0, |3-1|=2. Sorted: [0, 2, 2]. Result: 0.
Intuition
Sort the array. Adjacent pairs have the smallest gaps. Use a min-heap to explore larger gaps sequentially.
Detailed Dry Run
nums=[1,1,3], k=1 Heap: (0,1) dist 0, (1,2) dist 2. Pop (0,1). Result 0.
Intuition
Binary search for the distance such that there are at least pairs with distance . Counting is done in using two pointers.
Detailed Dry Run
nums=[1,1,3], k=1. Sorted: [1,1,3]. L=0, R=2. Mid=1. Count=2 >= 1. R=1. L=0, R=1. Mid=0. Count=1 >= 1. R=0. Result 0.
Minimum Time to Complete Trips
You are given an array time where time[i] denotes the time taken by the -th bus to complete one trip. Return the minimum time required for all buses to complete at least totalTrips trips.
Examples
Intuition
Iterate from time upwards and check if the total trips reaches totalTrips.
Detailed Dry Run
time = [1,2,3], totalTrips = 5
Intuition
The number of trips is monotone relative to time. We can binary search the answer range [1, min(time) * totalTrips].
Detailed Dry Run
| Step | L | R | Mid | Trips | Decision |
|---|---|---|---|---|---|
| 1 | 1 | 5 | 3 | 5 | R = 3 |
| 2 | 1 | 3 | 2 | 3 | L = 3 |
| Exit | - | - | - | - | Return 3 |
Maximum Running Time of N Computers
You have n computers and batteries. Return the maximum number of minutes you can run all n computers simultaneously.
Examples
Intuition
The maximum possible time is the average energy: .
Detailed Dry Run
n=2, batteries=[3,3,3]. Sum=9. Average=4.5. Result: 4.
Intuition
For a time , a battery with capacity can contribute at most minutes. Check if .
Detailed Dry Run
| Step | L | R | Mid | Energy | Needed | Decision |
|---|---|---|---|---|---|---|
| 1 | 1 | 4 | 3 | 9 | 6 | L = 3 |
| 2 | 3 | 4 | 4 | 9 | 8 | L = 4 |
| Exit | - | - | - | - | - | Return 4 |
Kth Smallest Element in a Sorted Matrix
Given an n x n matrix where each of the rows and columns are sorted in ascending order, return the k-th smallest element.
Examples
Intuition
This is equivalent to merging sorted lists. Use a min-heap to pick the smallest available element times.
Detailed Dry Run
matrix = [[1,5,9],[10,11,13],[12,13,15]], k=8 Heap: [(1,0,0), (10,1,0), (12,2,0)] Pop (1,0,0) -> Push (5,0,1). Pop (5,0,1) -> Push (9,0,2). ... 8th pop = 13.
Intuition
The value space is [matrix[0][0], matrix[n-1][n-1]]. For a value mid, we can count elements mid in by starting from the bottom-left corner.
Detailed Dry Run
| Step | L | R | Mid | Count | Decision |
|---|---|---|---|---|---|
| 1 | 1 | 15 | 8 | 2 | L = 9 |
| 2 | 9 | 15 | 12 | 6 | L = 13 |
| 3 | 13 | 15 | 14 | 9 | R = 14 |
| Exit | - | - | - | - | Return 13 |
Swim in Rising Water
On an grid, elevation at (i, j) is grid[i][j]. Return the least time such that you can swim from top-left to bottom-right.
Examples
Intuition
This is a variant of shortest path where the 'cost' of a path is elevations on path. Dijkstra's algorithm with a min-priority queue works perfectly.
Detailed Dry Run
grid = [[0,2],[1,3]].
Intuition
Treat the grid as a graph where each edge has a weight equal to the maximum elevation of its two endpoints. Sort all possible edge weights (or cell elevations). Add cells one by one in increasing order of elevation and connect them with their visited neighbors. The first time the top-left and bottom-right are in the same component, the current elevation is the answer.
Detailed Dry Run
grid = [[0,2],[1,3]].
Intuition
The answer lies in . For a fixed , we check if a path exists using only squares with elevation using BFS/DFS.
Detailed Dry Run
grid = [[0,2],[1,3]]. BS on range [0, 3]. Try T=2: Path (0,0)->(1,0) works, but (1,0) neighbors are (1,1) elev 3 > 2. Fails. Try T=3: Path (0,0)->(1,0)->(1,1) works! Possible. Result: 3.
Minimum Number of Days to Make m Bouquets
Return the minimum number of days such that you can make bouquets using adjacent flowers each. Each bouquet must consist of adjacent flowers.
Examples
Intuition
Try every possible day from to . For each day, check if it's possible to form bouquets.
Detailed Dry Run
bloomDay = [1,10,3,10,2], m=3, k=1. Sorted unique days: [1,2,3,10]. Day 1: 1 bouquet. Day 2: 2 bouquets. Day 3: 3 bouquets. Return 3.
Intuition
Instead of checking every day from 1 to maxD, only check days where at least one flower blooms. These are the unique values in bloomDay.
Detailed Dry Run
bloomDay = [1,10,3,10,2], m=3, k=1. Unique days sorted: [1, 2, 3, 10]. Check 1: 1 (fail), 2: 2 (fail), 3: 3 (pass). Result 3.
Intuition
The number of bouquets possible is a monotonic function of days. We can binary search the result in the range .
Detailed Dry Run
bloomDay = [1,10,3,10,2], m=3, k=1. Range [1, 10].
Find the Smallest Divisor Given a Threshold
Given an array nums and an integer threshold, find the smallest divisor such that the sum of the division results (rounded up) is threshold.
Examples
Intuition
Try every divisor from 1 up to and check the sum condition.
Detailed Dry Run
nums=[1,2,5,9], threshold=6.
Intuition
Instead of starting the brute force from , we can observe that must be at least . This provides a tighter lower bound for our search.
Detailed Dry Run
nums=[1,2,5,9], threshold=6. Sum=17. Lower bound .
Intuition
The sum of division results is a non-increasing function of the divisor . Binary search in the range .
Detailed Dry Run
nums=[1,2,5,9], threshold=6. [1, 9].
Koko Eating Bananas
Koko loves to eat bananas. There are n piles of bananas, the i-th pile has piles[i] bananas. The guards will come back in h hours. Koko can decide her bananas-per-hour eating speed k. Each hour, she chooses some pile of bananas and eats k bananas from that pile. If the pile has less than k bananas, she eats all of them instead and will not eat any more bananas during this hour. Return the minimum integer k such that she can eat all the bananas within h hours.
Examples
Intuition
Try every speed k starting from 1 upwards until we find one that allows Koko to finish in h hours.
Detailed Dry Run
piles=[3,6,7,11], h=8. Try k=1, 2, 3... until 4 fits.
Intuition
The time spent eating is a monotonic function of the speed k. We can binary search in the range [1, max(piles)].
Detailed Dry Run
piles=[3,6,7,11], h=8. L=1, R=11.
Help us improve! Report bugs or suggest new features on our Telegram group.