MindForge
MindForge
DashboardHelp & Support
Dashboard
MindForge

45-Day Interview Preparation Bootcamp

Course progress

0%
0 of 177 modules complete
Start Here0/1
  • How to Use This Course
Data Structures & Algorithms0/27
  • Arrays and Hashing
  • Two Pointers
  • Sliding Window
  • Sliding Window: Harder Problems
  • Binary Search
  • Stacks
  • Practice Test: Arrays, Pointers, Windows, Search and Stacks
  • Trees: Traversals and Core Patterns
  • Binary Search Trees and Rebuilding a Tree
  • Tries (Prefix Trees)
  • Heaps and Priority Queues
  • Graphs: BFS and DFS
  • Topological Sort and Cycle Detection
  • Union-Find (Disjoint Set Union)
  • Practice Test: Trees, Heaps and Graphs
  • Dynamic Programming Basics
  • Dynamic Programming: Two Dimensions
  • Dynamic Programming: Hard String Matching
  • Backtracking
  • Backtracking: Constraint Satisfaction
  • Greedy Algorithms
  • Interval Problems
  • Bit Manipulation
  • Math and Geometry
  • String Manipulation
  • Pattern Recall and Mock Coding Rounds
  • Practice Test: DP, Backtracking, Greedy and More

System Design

Foundations0/16
  • The System Design Interview Framework
  • Back-of-the-Envelope Estimation
  • Networking and Protocols for Design
  • API Design and Idempotency
  • Load Balancing, Proxies, and Scaling Out
  • Caching and CDNs
  • Choosing a Database: Storage, Indexes and Transactions
  • Replication, Partitioning, and Sharding
  • CAP, PACELC, and Levels of Consistency
  • Messaging, Queues, and Event-Driven Architecture
  • Distributed Transactions and Data Integrity
  • Coordination, Consensus, and Distributed Locks
  • Reliability, Resilience, and Rate Limiting
  • Observability, Security, and Cost
  • System Design Cheat Sheet
  • Practice Test: System Design Foundations
Case Studies0/23
  • Design a URL Shortener
  • Design a Rate Limiter
  • Design a Notification Service
  • Design a Job Queue System
  • Design a Chat App (WhatsApp)
  • Design an Analytics Pipeline
  • Design a Multi-tenant SaaS Architecture
  • Design a Social Media Feed (Twitter/X)
  • Design a Search Autocomplete System
  • Design a File Storage Service (Dropbox)
  • Design Google Docs
  • Design a Code Review System
  • Design Netflix
  • Design YouTube
  • Design Spotify
  • Design Uber/Lyft
  • Design Airbnb
  • Design Ticketmaster (Eventbrite)
  • Design an E-commerce Cart, Checkout, and Catalog
  • Design a Payment System
  • Design a Logging and Monitoring System
  • Mock Design Rounds
  • Practice Test: System Design Case Studies
Low-Level Design0/19
  • The LLD Interview Framework and UML
  • OOP Foundations for Design
  • SOLID Principles
  • Creational Patterns
  • Structural Patterns
  • Behavioral Patterns I — Strategy, Observer, Command, State, Template Method
  • Behavioral Patterns II and Anti-Patterns
  • Concurrency in Low-Level Design
  • Design a Parking Lot
  • Design an Elevator System
  • Design a Movie Ticket Booking System
  • Design an Expense-Sharing App (Splitwise)
  • Design a Vending Machine and an ATM
  • Design a Rate Limiter and a Logging Framework
  • Design a Notification Service and an In-Memory Cache
  • Design Games — Tic-Tac-Toe, Snake and Ladder, Chess
  • Database Design for LLD
  • LLD Cheat Sheet and Recall Drill
  • Practice Test: Low-Level Design

Backend

Python0/5
  • How Python Runs Your Code
  • Functions Deep Dive: Closures, Generators, Context Managers, Scope
  • Classes Deep Dive: Method Types, MRO, Metaclasses
  • Standard Library and Serialization
  • Practice Test: Python
Django0/6
  • Django Request Lifecycle
  • Lab: Django Middleware — Request ID & Response Time
  • Django ORM and Querysets
  • Django's Cache Framework
  • Practice Test: Django
  • Django in Production: Debugging Labs
FastAPI0/5
  • FastAPI, ASGI, and Async
  • FastAPI Dependency Injection
  • FastAPI Background Tasks
  • Lab: FastAPI Async — Concurrent Aggregation
  • Practice Test: FastAPI
Databases (PostgreSQL)0/6
  • Indexing
  • Query Optimization
  • Transactions and Isolation
  • Migrations and Schema Changes
  • Hierarchical Data and Safe Concurrent Updates
  • Practice Test: Databases
Caching, Queues & Distributed Systems0/8
  • Redis Caching
  • Redis Advanced Patterns
  • Celery and Background Workers
  • Kafka and Message Queues
  • Async Pipelines
  • Distributed Systems Basics
  • Distributed Locks
  • Practice Test: Caching, Queues and Distributed Systems
APIs, Security & Deployment0/9
  • REST API Design
  • API Versioning and Error Handling
  • API Security and Authentication
  • WebSockets and Real-Time Systems
  • Docker and Containers
  • File Storage with S3
  • Testing Strategies
  • Mock Backend Round
  • Practice Test: APIs, Security and Deployment
Frontend0/38
  • HTML Document Structure and Semantics
  • CSS Box Model, Flexbox and Grid
  • CSS Architecture and Theming
  • CSS and Rendering Performance
  • Variables, Scope, Hoisting, and Truthiness
  • Functions, this, and Binding
  • Objects and Prototypal Inheritance
  • JavaScript Utility Patterns: Cloning, Caching, and Memory
  • Promises From Scratch
  • The Event Loop and Browser Rendering Pipeline
  • The DOM: Nodes, Events, and Traversal
  • Practice Test: HTML, CSS and JavaScript
  • React Rendering Fundamentals
  • React Hooks Internals
  • React Performance
  • Lab: React — Stateful Counter Component
  • State Management
  • State Machines in React
  • React Custom Hooks and Composition Patterns
  • TypeScript for React
  • React Testing
  • Practice Test: React
  • HTTP and Caching
  • Network Performance and Web Vitals
  • Code Splitting and Bundles
  • Virtualization
  • GraphQL and Data Fetching
  • Web Security
  • WebSockets and Real-time
  • SSR and Next.js
  • Micro-frontends
  • Build Tools and Bundling
  • Accessibility
  • Error Handling
  • Internationalization
  • Animation
  • Rapid Recall and Mock Frontend Rounds
  • Practice Test: Performance, Architecture and Production
Behavioral & Interview Day0/14
  • Resume and Project Walkthroughs
  • The STAR Method and Refining Your Stories
  • Conflict and Difficult Coworkers
  • Failures, Incidents, and Obstacles
  • Leadership, Mentorship, and Ownership
  • Teamwork, Communication, and Feedback
  • Growth and Handling Ambiguity
  • Career Goals, Why This Company, and Negotiation
  • Situational Questions
  • Company Research
  • Mock Behavioral Rounds
  • Interview Day
  • After the Interview
  • Practice Test: Behavioral and Interview Day
Binary Search
Course contents

45-Day Interview Preparation Bootcamp

Course progress

0%
0 of 177 modules complete
Start Here0/1
  • How to Use This Course
Data Structures & Algorithms0/27
  • Arrays and Hashing
  • Two Pointers
  • Sliding Window
  • Sliding Window: Harder Problems
  • Binary Search
  • Stacks
  • Practice Test: Arrays, Pointers, Windows, Search and Stacks
  • Trees: Traversals and Core Patterns
  • Binary Search Trees and Rebuilding a Tree
  • Tries (Prefix Trees)
  • Heaps and Priority Queues
  • Graphs: BFS and DFS
  • Topological Sort and Cycle Detection
  • Union-Find (Disjoint Set Union)
  • Practice Test: Trees, Heaps and Graphs
  • Dynamic Programming Basics
  • Dynamic Programming: Two Dimensions
  • Dynamic Programming: Hard String Matching
  • Backtracking
  • Backtracking: Constraint Satisfaction
  • Greedy Algorithms
  • Interval Problems
  • Bit Manipulation
  • Math and Geometry
  • String Manipulation
  • Pattern Recall and Mock Coding Rounds
  • Practice Test: DP, Backtracking, Greedy and More

System Design

Foundations0/16
  • The System Design Interview Framework
  • Back-of-the-Envelope Estimation
  • Networking and Protocols for Design
  • API Design and Idempotency
  • Load Balancing, Proxies, and Scaling Out
  • Caching and CDNs
  • Choosing a Database: Storage, Indexes and Transactions
  • Replication, Partitioning, and Sharding
  • CAP, PACELC, and Levels of Consistency
  • Messaging, Queues, and Event-Driven Architecture
  • Distributed Transactions and Data Integrity
  • Coordination, Consensus, and Distributed Locks
  • Reliability, Resilience, and Rate Limiting
  • Observability, Security, and Cost
  • System Design Cheat Sheet
  • Practice Test: System Design Foundations
Case Studies0/23
  • Design a URL Shortener
  • Design a Rate Limiter
  • Design a Notification Service
  • Design a Job Queue System
  • Design a Chat App (WhatsApp)
  • Design an Analytics Pipeline
  • Design a Multi-tenant SaaS Architecture
  • Design a Social Media Feed (Twitter/X)
  • Design a Search Autocomplete System
  • Design a File Storage Service (Dropbox)
  • Design Google Docs
  • Design a Code Review System
  • Design Netflix
  • Design YouTube
  • Design Spotify
  • Design Uber/Lyft
  • Design Airbnb
  • Design Ticketmaster (Eventbrite)
  • Design an E-commerce Cart, Checkout, and Catalog
  • Design a Payment System
  • Design a Logging and Monitoring System
  • Mock Design Rounds
  • Practice Test: System Design Case Studies
Low-Level Design0/19
  • The LLD Interview Framework and UML
  • OOP Foundations for Design
  • SOLID Principles
  • Creational Patterns
  • Structural Patterns
  • Behavioral Patterns I — Strategy, Observer, Command, State, Template Method
  • Behavioral Patterns II and Anti-Patterns
  • Concurrency in Low-Level Design
  • Design a Parking Lot
  • Design an Elevator System
  • Design a Movie Ticket Booking System
  • Design an Expense-Sharing App (Splitwise)
  • Design a Vending Machine and an ATM
  • Design a Rate Limiter and a Logging Framework
  • Design a Notification Service and an In-Memory Cache
  • Design Games — Tic-Tac-Toe, Snake and Ladder, Chess
  • Database Design for LLD
  • LLD Cheat Sheet and Recall Drill
  • Practice Test: Low-Level Design

Backend

Python0/5
  • How Python Runs Your Code
  • Functions Deep Dive: Closures, Generators, Context Managers, Scope
  • Classes Deep Dive: Method Types, MRO, Metaclasses
  • Standard Library and Serialization
  • Practice Test: Python
Django0/6
  • Django Request Lifecycle
  • Lab: Django Middleware — Request ID & Response Time
  • Django ORM and Querysets
  • Django's Cache Framework
  • Practice Test: Django
  • Django in Production: Debugging Labs
FastAPI0/5
  • FastAPI, ASGI, and Async
  • FastAPI Dependency Injection
  • FastAPI Background Tasks
  • Lab: FastAPI Async — Concurrent Aggregation
  • Practice Test: FastAPI
Databases (PostgreSQL)0/6
  • Indexing
  • Query Optimization
  • Transactions and Isolation
  • Migrations and Schema Changes
  • Hierarchical Data and Safe Concurrent Updates
  • Practice Test: Databases
Caching, Queues & Distributed Systems0/8
  • Redis Caching
  • Redis Advanced Patterns
  • Celery and Background Workers
  • Kafka and Message Queues
  • Async Pipelines
  • Distributed Systems Basics
  • Distributed Locks
  • Practice Test: Caching, Queues and Distributed Systems
APIs, Security & Deployment0/9
  • REST API Design
  • API Versioning and Error Handling
  • API Security and Authentication
  • WebSockets and Real-Time Systems
  • Docker and Containers
  • File Storage with S3
  • Testing Strategies
  • Mock Backend Round
  • Practice Test: APIs, Security and Deployment
Frontend0/38
  • HTML Document Structure and Semantics
  • CSS Box Model, Flexbox and Grid
  • CSS Architecture and Theming
  • CSS and Rendering Performance
  • Variables, Scope, Hoisting, and Truthiness
  • Functions, this, and Binding
  • Objects and Prototypal Inheritance
  • JavaScript Utility Patterns: Cloning, Caching, and Memory
  • Promises From Scratch
  • The Event Loop and Browser Rendering Pipeline
  • The DOM: Nodes, Events, and Traversal
  • Practice Test: HTML, CSS and JavaScript
  • React Rendering Fundamentals
  • React Hooks Internals
  • React Performance
  • Lab: React — Stateful Counter Component
  • State Management
  • State Machines in React
  • React Custom Hooks and Composition Patterns
  • TypeScript for React
  • React Testing
  • Practice Test: React
  • HTTP and Caching
  • Network Performance and Web Vitals
  • Code Splitting and Bundles
  • Virtualization
  • GraphQL and Data Fetching
  • Web Security
  • WebSockets and Real-time
  • SSR and Next.js
  • Micro-frontends
  • Build Tools and Bundling
  • Accessibility
  • Error Handling
  • Internationalization
  • Animation
  • Rapid Recall and Mock Frontend Rounds
  • Practice Test: Performance, Architecture and Production
Behavioral & Interview Day0/14
  • Resume and Project Walkthroughs
  • The STAR Method and Refining Your Stories
  • Conflict and Difficult Coworkers
  • Failures, Incidents, and Obstacles
  • Leadership, Mentorship, and Ownership
  • Teamwork, Communication, and Feedback
  • Growth and Handling Ambiguity
  • Career Goals, Why This Company, and Negotiation
  • Situational Questions
  • Company Research
  • Mock Behavioral Rounds
  • Interview Day
  • After the Interview
  • Practice Test: Behavioral and Interview Day
Browsing without an account — progress is saved in this browser only.Sign in to save it

Binary Search

Reading105 min

Picture a guessing game: someone picks a whole number from 1 to 100, and after each guess they only say "higher" or "lower," never the number itself. Guess 50. Told "higher," guess 75. Told "lower," guess 62. Keep splitting whatever range is left in half, and you land on the exact number within 7 guesses, out of 100 possibilities. That is binary search: throw away half of what is left at every single step. It looks simple on paper, but small mistakes in exactly where the two boundaries sit cause an infinite loop the moment you write it live. Get the pattern right once, and it stops being just "search a sorted array." It also handles rotated arrays, 2D grids, and "find the best possible answer" optimization problems.

Search space reduction

In the guessing game above, the answer to "is the number higher than my guess?" flips from true to false exactly once as your guesses climb from 1 to 100. That one-way flip is what let you throw away half the range with full confidence every time. The technical name for that shape is monotonic: false for a run of values, then true for the rest (or the other way around), with exactly one flip point in between. Binary search works whenever you can define a monotonic yes/no rule over the search space. At each step you check the rule at the midpoint and throw away the half that cannot contain the answer. That guarantees the remaining space halves every step, which is what gives O(log n): a range of 100 shrinks to 50, then 25, then 12, then 6, then 3, then 1, about 7 steps, not 100 one-by-one guesses.

def binary_search(nums: list[int], target: int) -> int:
    lo, hi = 0, len(nums) - 1
    while lo <= hi:
        mid = lo + (hi - lo) // 2  # avoids overflow in other languages, good habit
        if nums[mid] == target:
            return mid
        elif nums[mid] < target:
            lo = mid + 1
        else:
            hi = mid - 1
    return -1

lo + (hi - lo) // 2 instead of (lo + hi) // 2 is a habit worth keeping even in Python, where integers never overflow. It shows you understand why the naive version breaks in languages with fixed-width integers.

Remember: binary search needs a monotonic yes/no rule: false, then true, with one flip point. Halving only works because of that.

Sign in to try this knowledge check.

Finding boundaries (lower bound, upper bound)

Picture a shelf of 1,000 books sorted by page count, with several books tied at exactly 300 pages. You want the position of the first 300-page book on the shelf, not just whether one exists. Many real problems ask exactly that: not "does target exist" but "where would target go" or "what is the first or last position satisfying a condition." That is a boundary search, and it needs a variant template that never lets lo and hi cross too early:

def lower_bound(nums: list[int], target: int) -> int:
    """First index where nums[index] >= target."""
    lo, hi = 0, len(nums)
    while lo < hi:
        mid = lo + (hi - lo) // 2
        if nums[mid] < target:
            lo = mid + 1
        else:
            hi = mid
    return lo

def upper_bound(nums: list[int], target: int) -> int:
    """First index where nums[index] > target."""
    lo, hi = 0, len(nums)
    while lo < hi:
        mid = lo + (hi - lo) // 2
        if nums[mid] <= target:
            lo = mid + 1
        else:
            hi = mid
    return lo

The key differences from the exact-match template: hi starts at len(nums) (one past the end, meaning "not found, insert here"), the loop condition is lo < hi (not <=), and there is no early return, since the loop converges with lo == hi landing on the answer. Mixing one template's conventions with the other's is the number one source of infinite loops.

Remember: exact match uses lo <= hi and mid ± 1. Boundary search uses lo < hi and hi = mid. Never mix them.

Sign in to try this knowledge check.

Monotonic functions and searching the answer

Picture 10 packages that need to ship within 5 days on trucks of some capacity C. With C = 1, the trucks crawl and shipping takes 20 days: too slow. With C = 1000, everything fits on one truck and ships in 1 day: done. Somewhere between 1 and 1000, the answer to "can we finish within 5 days?" flips from no to yes and stays yes. "Search the answer" problems like this one are not phrased as array search at all, but they hide that same monotonic rule. Binary search over the answer space itself, capacities from 1 to the total weight, applying the boundary-search template to find the smallest C where the rule flips to true.

Recognizing this shape, a yes/no question that flips one-directionally as some parameter increases, is what separates candidates who only know "binary search on a sorted array" from those who can apply it broadly.

Remember: if a yes/no question flips exactly once as a parameter grows, you can binary search that parameter, even if there's no array in sight.

Sign in to try this knowledge check.

Binary Search

Binary Search (LeetCode 704)

Intuition: The baseline exact-match template. Confirm you can write it cold, with correct bounds, in under a minute.

Approach: Standard lo <= hi loop, compare the midpoint to target, narrow to the half that cannot contain it.

def search(nums: list[int], target: int) -> int:
    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 -1

Complexity: Time O(log n), space O(1).

Common mistakes:

  • Using hi = len(nums) together with lo <= hi (mixing template conventions): causes an out-of-range access at nums[hi] when hi == len(nums).
  • Forgetting mid + 1 / mid - 1 and instead setting lo = mid / hi = mid, which can infinite-loop when lo and hi are adjacent.

Remember: the exact-match template narrows with mid + 1 / mid - 1, never plain mid.

Sign in to try this knowledge check.

Search in Rotated Sorted Array

Search in Rotated Sorted Array (LeetCode 33)

Intuition: The array is not fully sorted, but at any midpoint, at least one half (left-of-mid or mid-to-right) is guaranteed to be normally sorted. Figure out which half is sorted, then check whether the target lies in that half's range. If so, recurse there; if not, recurse into the other half.

Approach: Standard binary search loop, but before narrowing, check whether nums[lo..mid] is sorted by comparing nums[lo] and nums[mid].

def search_rotated(nums: list[int], target: int) -> int:
    lo, hi = 0, len(nums) - 1
    while lo <= hi:
        mid = lo + (hi - lo) // 2
        if nums[mid] == target:
            return mid

        if nums[lo] <= nums[mid]:  # left half is sorted
            if nums[lo] <= target < nums[mid]:
                hi = mid - 1
            else:
                lo = mid + 1
        else:  # right half is sorted
            if nums[mid] < target <= nums[hi]:
                lo = mid + 1
            else:
                hi = mid - 1
    return -1

Complexity: Time O(log n), space O(1).

Common mistakes:

  • Using < instead of <= when checking nums[lo] <= nums[mid]. With only one element, or two equal boundary values, this misclassifies which half is sorted.
  • Getting the boundary comparisons wrong (nums[lo] <= target < nums[mid]), missing a target that sits exactly at a boundary.

Remember: one half of a rotated array is always fully sorted. Find which one, then check if the target's range fits inside it.

Sign in to try this knowledge check.

Find Minimum in Rotated Sorted Array

Find Minimum in Rotated Sorted Array (LeetCode 153)

Intuition: The minimum is the rotation's "pivot point," the one place where nums[i] > nums[i+1]. Compare the midpoint to the rightmost element: if nums[mid] > nums[hi], the minimum must be to the right of mid, since the rotation point has not been passed yet. Otherwise it is at or to the left of mid.

Approach: A boundary-search style loop narrowing toward the pivot.

def find_min(nums: list[int]) -> int:
    lo, hi = 0, len(nums) - 1
    while lo < hi:
        mid = lo + (hi - lo) // 2
        if nums[mid] > nums[hi]:
            lo = mid + 1
        else:
            hi = mid
    return nums[lo]

Complexity: Time O(log n), space O(1).

Common mistakes:

  • Comparing nums[mid] to nums[lo] instead of nums[hi]. This breaks when the left half itself is the sorted, non-rotated portion.
  • Using lo <= hi here instead of lo < hi. This template converges to a single index and does not need the equality case.

Remember: compare nums[mid] against nums[hi], not nums[lo], to find which side the rotation pivot is on.

Sign in to try this knowledge check.

Search a 2D Matrix

Search a 2D Matrix (LeetCode 74)

Intuition: If each row is sorted and the first element of each row is greater than the last element of the previous row, the whole matrix is really a single sorted 1D array wearing a 2D shape. You can binary search over the flattened index space and convert back to (row, col).

Approach: Binary search over indices 0 to rows*cols - 1, converting a flat index to (row, col) with divmod.

def search_matrix(matrix: list[list[int]], target: int) -> bool:
    if not matrix or not matrix[0]:
        return False
    rows, cols = len(matrix), len(matrix[0])
    lo, hi = 0, rows * cols - 1

    while lo <= hi:
        mid = lo + (hi - lo) // 2
        row, col = divmod(mid, cols)
        val = matrix[row][col]
        if val == target:
            return True
        elif val < target:
            lo = mid + 1
        else:
            hi = mid - 1
    return False

Complexity: Time O(log(rows·cols)), space O(1).

Common mistakes:

  • Running two separate binary searches, one to find the row and one within it. Correct and still O(log n), but more code and more places to get bounds wrong than the flattened-index trick.
  • Getting divmod(mid, cols) backwards (col, row instead of row, col).

Every problem in this lesson is one of two templates wearing a different costume: exact-match (lo <= hi, mid ± 1) or boundary-search (lo < hi, hi = mid on the "keep" branch). The rotated-array and matrix problems still narrow to an exact target, so they use the exact-match shape. Finding a boundary or a pivot uses the converging shape instead. Pick the template from what the problem asks (exact value vs. a boundary), then apply it mechanically. Most binary search bugs come from borrowing one template's loop condition with the other's update rule.

Remember: a sorted-rows matrix with each row starting above the previous row's end is one flat sorted array in disguise. Binary search the flat index.

Sign in to try this knowledge check.
PreviousSliding Window: Harder ProblemsNextStacks

Course progress

0%
0 of 177 modules complete

On this page

  • Search space reduction
  • Finding boundaries (lower bound, upper bound)
  • Monotonic functions and searching the answer
  • Binary Search
  • Search in Rotated Sorted Array
  • Find Minimum in Rotated Sorted Array
  • Search a 2D Matrix