Skip to Content
Course content

177: Implementing Binary Search

Click on the "Edit" button in the top corner of the screen to edit your slide content.

How do I actually translate the "divide and conquer" logic into JavaScript?

When you're implementing binary search, you aren't just looping through a list; you're shrinking the search area. I find it easiest to think of it as two pointers—low and high—that act like walls closing in on your target. You keep checking the middle element, and depending on whether your target is higher or lower, you move one of those walls.

Let's say we have a sorted list of employee IDs and we're looking for ID 1042. Here is how I'd write that:

function binarySearch(sortedArray, target) {
  let low = 0;
  let high = sortedArray.length - 1;

  while (low <= high) {
    const mid = Math.floor((low + high) / 2);
    const guess = sortedArray[mid];

    if (guess === target) {
      return mid; // Found it!
    }
    if (guess > target) {
      high = mid - 1; // Target is in the left half
    } else {
      low = mid + 1; // Target is in the right half
    }
  }

  return -1; // Target isn't in the array
}

const employeeIds = [101, 205, 310, 450, 1042, 1100, 1250];
console.log(binarySearch(employeeIds, 1042)); // 4

Why is the sorted array a hard requirement?

This is the most common point of confusion. Binary search relies on a fundamental assumption: if the middle element is larger than your target, every single element to the right of that middle point must also be larger than your target. That's the only reason we can safely throw away half the array in one go.

If the array is unsorted, that logic collapses. Imagine looking for the number 10 in [20, 5, 10, 2, 15]. If your midpoint is 10, you're lucky. But if your midpoint is 5, and you assume that because 5 is less than 10, the target must be to the right, you might be right this time—but you've lost the ability to prove it. In an unsorted list, the target could be anywhere, so you're forced back into a linear search (checking every single item), which defeats the whole purpose of using this algorithm.

Why do I need Math.floor() when calculating the midpoint?

Coming from languages like Java or C++, you might be used to integer division where 5 / 2 just equals 2. JavaScript doesn't work like that. In JS, (0 + 5) / 2 gives you 2.5.

Since array indices must be integers, trying to access sortedArray[2.5] will just return undefined, and your logic will break immediately. I always use Math.floor() to round down to the nearest whole number. It doesn't matter if you round up or down, as long as you are consistent and end up with a valid index.

Is binary search always the "better" choice?

Not necessarily. It's incredibly fast—O(log n) time complexity, for the math nerds—but it comes with a "cost of entry." That cost is the sorting.

If you have a list that is already sorted, binary search is a no-brainer. But if you have an unsorted list and you only need to search it once, it's actually faster to just do a linear search. Why? Because sorting an array usually takes O(n log n) time, which is more expensive than a simple O(n) linear scan. I only reach for binary search when the data is already sorted, or when I'm sorting the data once and then performing hundreds of searches over time.




📋 Practical Task

Implement a Sorted Transaction Finder

You are building a financial ledger tool. You have an array of transaction IDs that are already sorted in ascending order. Your task is to implement the findTransactionIndex function using the binary search algorithm.

Requirements:

  • The function should take two arguments: the transactions array and the targetId.
  • If the targetId exists in the array, return its index.
  • If the targetId does not exist, return -1.
  • Do not use built-in JavaScript methods like indexOf() or findIndex(), as the goal is to implement the binary search logic manually.
const transactions = [10023, 10045, 10089, 10112, 10150, 10201, 10255];

function findTransactionIndex(transactions, targetId) {
  // Your code here
}

// Test cases:
console.log(findTransactionIndex(transactions, 10150)); // Should return 4
console.log(findTransactionIndex(transactions, 10023)); // Should return 0
console.log(findTransactionIndex(transactions, 99999)); // Should return -1
Rating
0 0

There are no comments for now.

to be the first to leave a comment.