Sorting & Binary Search 101
Fundamental · 4 chapters · 8 min read · Halve the search space every step, on arrays and on the answer itself.
Practise this in the app All guides
Why sorting and binary search go together
Order is information
Sorting costs O(n log n), but it buys a lot: equal items become neighbours, the smallest and largest are at the ends, and most importantly you can binary search. Binary search finds a position in a sorted sequence in O(log n) by comparing with the middle element and throwing away the half that cannot contain the answer. For a million elements that is about 20 comparisons.
Signals in a problem statement
- The input is already sorted or rotated sorted.
- "Find the position", "insert position", "first or last occurrence".
- The required complexity is O(log n) — almost always binary search.
- "Find the minimum speed, capacity or days such that a condition holds" — binary search on the answer.
- "Square root", "k-th smallest" in a structured space.
- "Arrange numbers to form the largest number", "sort by a custom rule" — a custom comparator.
Binary search on the answer
This is the version that separates strong candidates. If you can write a function ok(x) that answers "is x big enough?", and ok is monotonic (once true, it stays true for every larger x), then you can binary search over x itself, even if there is no array. Example: "What is the slowest eating speed that finishes all bananas in h hours?" Faster speeds always finish; slower ones might not. So search the speed range 1..max(piles) for the first speed where ok becomes true.
Mental model
Think of the search space as a row of answers F F F F T T T. Your job is to find the first T. Every template in the next chapter is a careful way of doing exactly that without an infinite loop.
Core patterns with templates
1. First index where a condition becomes true
This single template covers insert position, lower bound and binary search on the answer.
def first_true(lo, hi, ok):
# search in [lo, hi); returns hi if ok is never true
while lo < hi:
mid = (lo + hi) // 2
if ok(mid):
hi = mid
else:
lo = mid + 1
return lo
Insert position of target in sorted a: first_true(0, len(a), lambda i: a[i] >= target). Python's bisect.bisect_left(a, target) does the same thing.
2. Binary search on the answer
def min_eating_speed(piles, h):
def ok(speed):
return sum((p + speed - 1) // speed for p in piles) <= h
return first_true(1, max(piles) + 1, ok)
Example: piles [3, 6, 7, 11], h = 8. Speed 4 needs 1 + 2 + 2 + 3 = 8 hours, speed 3 needs 10, so the answer is 4.
3. Integer square root
def isqrt(x):
return first_true(0, x + 2, lambda m: m * m > x) - 1
4. Rotated sorted array
One half around mid is always sorted. Decide which, then check whether the target lies inside it.
def search_rotated(a, t):
lo, hi = 0, len(a) - 1
while lo <= hi:
mid = (lo + hi) // 2
if a[mid] == t:
return mid
if a[lo] <= a[mid]:
if a[lo] <= t < a[mid]:
hi = mid - 1
else:
lo = mid + 1
else:
if a[mid] < t <= a[hi]:
lo = mid + 1
else:
hi = mid - 1
return -1
5. Custom sort order
from functools import cmp_to_key
def largest_number(nums):
s = [str(x) for x in nums]
s.sort(key=cmp_to_key(lambda a, b: (b + a > a + b) - (b + a < a + b)))
out = "".join(s)
return "0" if out[0] == "0" else outComplexity, mistakes and edge cases
Complexity
| Task | Time | Space |
|---|---|---|
Python sort (Timsort) | O(n log n) | O(n) worst case |
| Binary search on an array | O(log n) | O(1) |
| Binary search on the answer | O(log R × cost of ok) | depends on ok |
For Koko-style problems with range R up to 10⁹ and ok costing O(n), the total is about 30 × n operations, which is comfortably fast.
Common mistakes
- Infinite loops. With
lo < hi, always uselo = mid + 1on the false branch andhi = midon the true branch. Mixinghi = mid - 1into this template skips answers. - Mixing templates. The closed-interval
lo <= histyle (used for the rotated array) and the half-openlo < histyle each have their own update rules. Pick one per problem and keep its invariant. - Wrong range for the answer. The search range must definitely contain the answer; for Koko the upper end is
max(piles), notsum(piles), and the lower end is 1, not 0 (division by zero). - Non-monotonic condition. If
okcan go true, false, true, binary search will give nonsense. Prove monotonicity in one sentence before coding. - Integer overflow in
(lo + hi) / 2in Java or C++; uselo + (hi - lo) / 2. Python integers do not overflow, but mention it. - Ceil division.
(p + s - 1) // savoids floating point. - Duplicates in rotated arrays break the "which half is sorted" test when
a[lo] == a[mid] == a[hi]; then shrink both ends by one, making the worst case O(n).
Edge cases
Empty array, one element, target smaller than all or larger than all, all elements equal, rotation by 0 (not rotated), x = 0 or 1 for square root, and a list of zeros for "largest number" (answer "0", not "000").
Variations and practise
How interviewers twist it
- First and last occurrence. Run
first_truetwice: once witha[i] >= t, once witha[i] > t; the range is[first, second - 1]. - Peak element. Compare
a[mid]witha[mid + 1]: if it is rising, a peak lies to the right. - Minimum in a rotated array. Compare
a[mid]witha[hi]to decide which side holds the drop. - Search a 2D matrix. Treat a row-major sorted matrix as a flat array with
r, c = divmod(mid, cols). - Capacity, days, distance. "Ship packages within D days", "split array into k parts with smallest maximum sum", "place cows as far apart as possible" — all are binary search on the answer with a greedy
ok. - Median of two sorted arrays. Binary search on how many elements to take from the shorter array so the left halves balance. Hard, but it rewards a clear invariant: everything in the combined left half is no larger than everything in the right half.
- Sorting knowledge. Be ready to explain merge sort and quicksort, stability, and why Python's sort is stable.
How to explain it
Say the shape aloud: "ok(speed) is false for small speeds and true for large ones, so I binary search for the first true." This sentence alone often earns the interviewer's nod.
Practise
The problems below go from insert position and square root to rotated arrays, binary search on the answer, a custom sort comparator, and finally the median of two sorted arrays. Use one template consistently across all of them.
Practise
Easy
- 1486. Search Insert Position
- 1487. Sqrt(x)
- 1493. Exact Match in a Sorted Ledger
- 1498. Count Copies on a Sorted Shelf
- 1499. First Failing Nightly Build
- 1500. Next Word at or After a Query
- 1501. Count the Midpoint Guesses
- 1502. Full Tiers of a Can Pyramid
- 1503. Order Runners by Finish Time
- 1504. Evens Before Odds, Order Kept
- 1505. Sort by Lit Bits
- 1506. Arrange Stock by a Priority List
- 1507. Squared Readings in Order
- 1508. Closest Neighbor Pairs
- 1509. Can the Steps Be Made Even?
- 1510. Out of Place in the Photo
- 1511. Best Product of Three
- 1512. Pair Up for the Largest Minimums
- 1513. Widest Fence Triangle
- 1514. Names by Length, Then Alphabet
- 1515. Union of Two Sorted Rosters
- 1516. Shared Items With Repeats
- 1517. Missing Step in a Progression
- 1518. Index That Names Itself
- 1519. Count Sub-Zero Readings in a Sorted Grid
- 1520. Summit of a Trail
- 1521. Affordable Items per Budget
- 1522. Self-Counting Threshold
- 1523. K-th Absent Ticket Number
- 1524. Best Pair Under the Cap
- 1525. Restore the Tagged Sentence
- 1526. Replace Values With Ranks
- 1527. Top Three Quiz Average
- 1528. Smaller-Than-Me Tally
- 1529. Load the Van for Most Units
- 1530. Seat Every Guest
- 1531. Tightest Group of K Scores
- 1532. Roll Call, Tallest First
- 1533. Was It a Rotated Sorted List?
- 1534. Pairs Below the Target
- 1535. Closest Cross Pair
- 1536. Rarest First Ordering
- 1537. Weakest Squads
- 1538. Where the Target Lands
- 1539. Dominant Sign Count
- 1540. Fair Card Trade
- 1541. Third Item Free
- 1542. Most Treats for the Coins
- 1543. Two-Lane Sort
- 1544. Split the PIN Digits
- 1545. Lower Bound in a Descending List
- 1546. Closest Reading to a Value
- 1547. Ticket Owner Lookup
- 1548. Adjacent Swaps to Sort Bits
- 1549. Trimmed Mean of Ratings
- 1550. Distinct Pair Averages
- 1551. Words Follow the Custom Alphabet
- 1552. Cube Root by Bisection
- 1553. How Many Cheap Items Fit the Budget
- 1554. Quarter Majority in a Sorted List
- 1555. Far-Apart Elements
- 1556. Widest Empty Strip
- 1557. Cells by Distance From a Start
- 1558. Sort Huge Numerals
- 1559. Vowels in Order
- 1560. Calendar Dates in Order
- 1561. League Table Order
- 1673. Bucket Scores by Decile
- 1674. Radix Sort the Codes
- 1675. One Partition Pass
- 1676. Galloping Search From the Start
- 1678. Group Badges by Department
- 1680. Interleave Two Sorted Streams Evenly
- 1683. Order Tasks by Deadline Then Length
- 1687. Stable Sorts in Sequence
Medium
- 1488. Search in Rotated Sorted Array
- 1489. Koko Eating Bananas
- 1490. Largest Number
- 1494. First and Last Sighting
- 1495. The Unpaired Locker Key
- 1496. Lowest Point After Rotation
- 1562. Lookup in a Rotated List With Repeats
- 1563. Search a Mountain Profile
- 1564. Search a Flattened Grid
- 1565. Staircase Search in a Sorted Grid
- 1566. K-th Smallest in a Sorted Grid
- 1567. K Readings Nearest a Target
- 1568. Citation Threshold on a Sorted List
- 1569. Next Starting Slot
- 1570. Versioned Sensor Lookup
- 1571. Potent Pairs per Catalyst
- 1572. Best-Paying Gig per Worker
- 1573. Pairs With a Sum in a Band
- 1574. Count Valid Triangles
- 1575. Fewest Rafts
- 1576. Three-Tag Partition
- 1577. Top K Busiest Values
- 1578. Follow the House Alphabet
- 1579. Arrange the Server Logs
- 1580. Rebuild the Lineup
- 1581. Peak Concurrent Sessions
- 1582. Convoys on the Highway
- 1583. Most Duel Wins
- 1584. Unique Tag Increments
- 1585. Pairs of Halves and Doubles
- 1586. Widest Gap in Linear Time
- 1587. Balanced Pair Sums
- 1588. Flatten the Staircase
- 1589. Most Common After Boosts
- 1590. Cost to Level to Each Query
- 1591. One Swap to Shrink the Error
- 1592. Spread Out the Beacons
- 1593. Earliest Day for Bouquets
- 1594. Time for All Deliveries
- 1595. Cut Equal Rope Pieces
- 1597. N-th Multiple of Any
- 1598. Garage Repair Deadline
- 1599. Cover Houses With Hotspots
- 1600. K-th Smallest Run Sum
- 1601. Inversion Tally
- 1602. Sort a Chain
- 1603. Merge Many Sorted Batches
- 1604. Rank by Step Count
- 1605. Ranked-Choice Team Order
- 1606. Sort by Remapped Digits
- 1607. Most Removals Keeping a Pattern
- 1608. Largest Cheap Square
- 1609. Tallest Tower on a Budget
- 1610. Closest P Pairs
- 1611. The Cautious Burglar
- 1612. Least-Effort Route
- 1613. Visitors Who See Blooms
- 1614. K-th Smallest Fraction
- 1615. Typeahead Suggestions
- 1616. Longest Word From Letter Deletions
- 1617. Sort Without the Library
- 1618. Gather at the Median
- 1619. Last-Minute Boarding
- 1620. Hold Off the Waves
- 1621. Smoothed Maximum
- 1622. Sort Within Bit Groups
- 1623. Natural Order Filenames
- 1624. Release Versions in Order
- 1625. Points Around the Origin
- 1626. Widest Pair Across Falling Lists
- 1627. Longest Quiet Stretch of Floors
- 1628. Value Frequency in a Range
- 1629. Leader at Each Moment
- 1630. Items Between Markers
- 1631. Bounded Sum Subsequences
- 1632. Coin Reach
- 1633. Two-Office Split
- 1634. Fewest Distinct After Removals
- 1635. Paired Score With K Picks
- 1636. Smallest Common Row Value
- 1637. The Repeated Badge
- 1638. Closest Pair at Least X Apart
- 1639. Square Orchard for a Harvest
- 1640. Ordered Three-Way Splits
- 1641. Closest Cap to a Target
- 1642. Stable Pivot Arrangement
- 1643. Search a Nearly Sorted List
- 1644. Sort a Nearly Sorted Feed
- 1645. Count Distinct by Galloping
- 1646. Leftmost Lit Column
- 1647. Room Booking Ledger
- 1648. Widest Spread Across Lists
- 1649. Equal Window Sums Cost
- 1650. Mark and Score
- 1651. Smallest Arrangement Within a Limit
- 1652. Mark Pairs: Half and Double
- 1653. Fill the Sack by Value Density
- 1654. Shortest Window to Sort
- 1655. Widest Ascending Ramp
- 1656. A Planet Absorbs Asteroids
- 1657. Assign Cores to Processors
- 1658. Local Equals Global Disorder
- 1659. Sparse Shelf Search
- 1660. Raise the Median
- 1661. Lowest Peak After Left Shifts
- 1662. Best Carpet Coverage
- 1663. Maximum Alloy Batches
- 1664. Drop Columns for Order
- 1665. Change Three to Narrow the Range
- 1666. Shift Up or Down by K
- 1667. Fewest Tight Batches
- 1668. Keep the Prefix Positive
- 1669. Labelled Picks Under Caps
- 1670. Tightest Clock Gap
- 1671. Median of Sorted Rows
- 1672. Insertion Sort Shift Log
- 1677. Count Pairs Above a Ratio
- 1679. Day the Savings Goal Is Met
- 1681. Longest Sorted Run With One Removal
- 1682. Triplets Within a Spread
- 1684. Next Larger Value Anywhere
- 1685. Fit Heights Into a Band
- 1686. Smallest Digit Arrangement
- 1688. Boxes Into a Narrow Warehouse
- 1689. Chain Sorted by Magnitude
- 1690. Count Undominated Points
- 1691. Fewest Moves to the Front
- 1746. Sort by Prefix Reversals Count
- 1753. Earliest Second All Marked
Hard
- 1491. Median of Two Sorted Arrays
- 1492. Split Array Largest Sum
- 1497. Lowest Point Rotated with Repeats
- 1596. K-th Cell of a Times Table
- 1692. K-th Amount From Single Coin Types
- 1693. Longest Shared Uptime
- 1694. Add Refuel Stops to Shrink Gaps
- 1695. Smaller Ones to the Right
- 1696. Count Lopsided Pairs
- 1697. Narrowest Range Touching Every List
- 1698. Most Profitable Gig Schedule
- 1699. Best K Festival Visits
- 1700. Nesting Parcels
- 1701. Insertions to Embed a Sequence
- 1702. Carve a Ridge
- 1703. Best Rectangle Under a Ceiling
- 1704. Trailing Zero Preimages
- 1705. All-Ones Base
- 1706. Corner Block Pile
- 1707. Split Chores Among Workers
- 1708. Orchard Walk Within Steps
- 1709. Brightest Weakest District
- 1710. Hens and Grain
- 1711. K-th Product of Two Sorted Lists
- 1712. Assign Tasks With Boost Pills
- 1713. Courses Before Deadlines
- 1714. Cheapest Crew of K
- 1715. Earliest Full Harvest
- 1716. Starting Stamina for All Trials
- 1717. Weighted Levelling Cost
- 1718. Most Chunks With Repeats
- 1719. Raise the Ladder
- 1720. Near Twins Nearby
- 1721. Make a Gapless Run
- 1722. Tallest Crate Stack
- 1723. Doubled Window Medians
- 1724. Fewest Egg Trials
- 1725. Growing Team Rounds
- 1726. Closest Subset Total
- 1727. Tallest Towers Under Zoning
- 1728. Best Average of Long Runs
- 1729. Median of Distinct Counts
- 1730. Time to Shrink the Total
- 1731. Dominant Pair Queries
- 1732. Nearest Adequate Room
- 1733. Shortest Slot for Each Query
- 1734. Rebuild From Shifted Copies
- 1735. Rebuild From Subset Totals
- 1736. Parity-Matched Similarity
- 1737. Marble Bag Spread
- 1738. Robots to Repair Bays
- 1739. Trim a Segment to Sort
- 1740. Floored Ratio Total
- 1741. Guards on a Square Fence
- 1742. Count Strictly Increasing Picks
- 1743. Least Edits to Make Monotone
- 1744. Sort With One Empty Slot
- 1745. K-th Smallest Run Maximum
- 1747. Sort With Distance-Limited Swaps
- 1748. Gather K Flags Side by Side
- 1749. Total Imbalance of Runs
- 1750. Runs With Median K
- 1751. Fill Blanks With Two Values
- 1752. Range of Sorted Run Sums
- 1754. Garden Beauty With Extra Seeds
- 1755. Drop One Point to Shrink the Spread