{
  "id": "searching/binary-search",
  "version": 1,
  "deterministic": true,
  "url": "/dsa/searching/binary-search",
  "topic": {
    "slug": "searching",
    "title": "Searching"
  },
  "title": "Binary Search",
  "tagline": "Throw away half the list with every single question.",
  "vizKind": "array",
  "complexity": {
    "time": {
      "best": "O(1)",
      "average": "O(log n)",
      "worst": "O(log n)"
    },
    "space": "O(1)",
    "growth": "log",
    "note": "Every look halves what's left. To go from 1,000,000 items to 1 you only need to halve about 20 times — so 20 looks is the *worst* case on a million items."
  },
  "code": {
    "javascript": "function binarySearch(a, target) {\n  let low = 0;\n  let high = a.length - 1;\n  while (low <= high) {\n    const mid = Math.floor((low + high) / 2);\n    if (a[mid] === target) return mid;\n    if (a[mid] < target) low = mid + 1;\n    else high = mid - 1;\n  }\n  return -1;\n}",
    "python": "def binary_search(a, target):\n    low = 0\n    high = len(a) - 1\n    while low <= high:\n        mid = (low + high) // 2\n        if a[mid] == target: return mid\n        if a[mid] < target: low = mid + 1\n        else: high = mid - 1\n\n    return -1\n",
    "java": "int binarySearch(int[] a, int target) {\n  int low = 0;\n  int high = a.length - 1;\n  while (low <= high) {\n    int mid = low + (high - low) / 2;\n    if (a[mid] == target) return mid;\n    if (a[mid] < target) low = mid + 1;\n    else high = mid - 1;\n  }\n  return -1;\n}",
    "cpp": "int binarySearch(vector<int> a, int target) {\n  int low = 0;\n  int high = a.size() - 1;\n  while (low <= high) {\n    int mid = low + (high - low) / 2;\n    if (a[mid] == target) return mid;\n    if (a[mid] < target) low = mid + 1;\n    else high = mid - 1;\n  }\n  return -1;\n}"
  },
  "defaultInput": [
    3,
    7,
    12,
    18,
    24,
    31,
    40,
    55,
    63,
    77,
    82,
    91
  ],
  "defaultTarget": 63,
  "inputHint": "Type a list (it gets sorted for you) and a number to find.",
  "pitfalls": [
    {
      "wrong": "Running binary search on an unsorted list.",
      "right": "It will confidently return the wrong answer. Sorted order is the assumption that makes 'throw away half' valid — without it, the algorithm is nonsense."
    },
    {
      "wrong": "Writing `while (low < high)` instead of `while (low <= high)`.",
      "right": "With `<`, the window can shrink to a single box and you never look at it — so you miss values that were right there. The window is only truly empty once low passes high."
    },
    {
      "wrong": "Computing the middle as (low + high) / 2 in a language with fixed-size integers.",
      "right": "On huge arrays low + high can overflow and go negative. Use low + (high − low) / 2. This exact bug sat in the Java standard library for nine years."
    },
    {
      "wrong": "Forgetting the +1 and −1 when narrowing the window.",
      "right": "You already checked the middle. If you set low = mid instead of mid + 1, the window stops shrinking and your program hangs forever."
    }
  ],
  "quiz": [
    {
      "q": "A sorted list has 1,000,000 items. What is the worst-case number of looks?",
      "options": [
        "About 1,000,000",
        "About 1,000",
        "About 20",
        "About 500,000"
      ],
      "answer": 2,
      "why": "Each look halves the list. Halving a million down to one takes about 20 steps, because 2²⁰ is just over a million."
    },
    {
      "q": "Why does binary search insist the list is sorted?",
      "options": [
        "So it looks tidy",
        "Because one look then tells you about every item on that side",
        "So there are no duplicates",
        "It doesn't — that's a myth"
      ],
      "answer": 1,
      "why": "Sorted order is what makes 'everything to the left is smaller' true. That single guarantee is what lets you discard half the list without checking it."
    },
    {
      "q": "You double the list from 1,000 to 2,000 items. How many extra looks does binary search need?",
      "options": [
        "Twice as many",
        "1,000 more",
        "One more",
        "None"
      ],
      "answer": 2,
      "why": "One. Doubling the data adds a single halving step. That is why O(log n) barely notices data growing."
    }
  ],
  "problems": [
    {
      "name": "Binary Search",
      "difficulty": "Easy",
      "url": "https://leetcode.com/problems/binary-search/"
    },
    {
      "name": "Search Insert Position",
      "difficulty": "Easy",
      "url": "https://leetcode.com/problems/search-insert-position/"
    },
    {
      "name": "First Bad Version",
      "difficulty": "Easy",
      "url": "https://leetcode.com/problems/first-bad-version/"
    },
    {
      "name": "Find Minimum in Rotated Sorted Array",
      "difficulty": "Medium",
      "url": "https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/"
    }
  ],
  "trace": {
    "note": "Each frame is one immutable step: data snapshot, pointers, per-index roles, executing code line, and a one-sentence explanation.",
    "length": 6,
    "frames": [
      {
        "data": [
          {
            "id": "c0-3",
            "value": 3
          },
          {
            "id": "c1-7",
            "value": 7
          },
          {
            "id": "c2-12",
            "value": 12
          },
          {
            "id": "c3-18",
            "value": 18
          },
          {
            "id": "c4-24",
            "value": 24
          },
          {
            "id": "c5-31",
            "value": 31
          },
          {
            "id": "c6-40",
            "value": 40
          },
          {
            "id": "c7-55",
            "value": 55
          },
          {
            "id": "c8-63",
            "value": 63
          },
          {
            "id": "c9-77",
            "value": 77
          },
          {
            "id": "c10-82",
            "value": 82
          },
          {
            "id": "c11-91",
            "value": 91
          }
        ],
        "pointers": [],
        "highlights": [],
        "codeLine": 1,
        "variables": {
          "target": 63,
          "size": 12
        },
        "explanation": "Looking for 63 in a sorted list. Because it is sorted, we can throw away half of it with a single question.",
        "stats": {
          "comparisons": 0,
          "swaps": 0
        }
      },
      {
        "data": [
          {
            "id": "c0-3",
            "value": 3
          },
          {
            "id": "c1-7",
            "value": 7
          },
          {
            "id": "c2-12",
            "value": 12
          },
          {
            "id": "c3-18",
            "value": 18
          },
          {
            "id": "c4-24",
            "value": 24
          },
          {
            "id": "c5-31",
            "value": 31
          },
          {
            "id": "c6-40",
            "value": 40
          },
          {
            "id": "c7-55",
            "value": 55
          },
          {
            "id": "c8-63",
            "value": 63
          },
          {
            "id": "c9-77",
            "value": 77
          },
          {
            "id": "c10-82",
            "value": 82
          },
          {
            "id": "c11-91",
            "value": 91
          }
        ],
        "pointers": [
          {
            "name": "low",
            "index": 0
          },
          {
            "name": "high",
            "index": 11
          }
        ],
        "highlights": [],
        "codeLine": 3,
        "variables": {
          "low": 0,
          "high": 11,
          "target": 63
        },
        "explanation": "The answer, if it exists, is somewhere between position 0 and position 11. That is our search window.",
        "stats": {
          "comparisons": 0,
          "swaps": 0
        }
      },
      {
        "data": [
          {
            "id": "c0-3",
            "value": 3
          },
          {
            "id": "c1-7",
            "value": 7
          },
          {
            "id": "c2-12",
            "value": 12
          },
          {
            "id": "c3-18",
            "value": 18
          },
          {
            "id": "c4-24",
            "value": 24
          },
          {
            "id": "c5-31",
            "value": 31
          },
          {
            "id": "c6-40",
            "value": 40
          },
          {
            "id": "c7-55",
            "value": 55
          },
          {
            "id": "c8-63",
            "value": 63
          },
          {
            "id": "c9-77",
            "value": 77
          },
          {
            "id": "c10-82",
            "value": 82
          },
          {
            "id": "c11-91",
            "value": 91
          }
        ],
        "pointers": [
          {
            "name": "low",
            "index": 0
          },
          {
            "name": "mid",
            "index": 5
          },
          {
            "name": "high",
            "index": 11
          }
        ],
        "highlights": [
          {
            "index": 5,
            "role": "active"
          }
        ],
        "codeLine": 5,
        "variables": {
          "low": 0,
          "mid": 5,
          "high": 11,
          "window": 12
        },
        "explanation": "12 boxes left in the window. Look at the middle one: position 5, holding 31.",
        "stats": {
          "comparisons": 0,
          "swaps": 0
        }
      },
      {
        "data": [
          {
            "id": "c0-3",
            "value": 3
          },
          {
            "id": "c1-7",
            "value": 7
          },
          {
            "id": "c2-12",
            "value": 12
          },
          {
            "id": "c3-18",
            "value": 18
          },
          {
            "id": "c4-24",
            "value": 24
          },
          {
            "id": "c5-31",
            "value": 31
          },
          {
            "id": "c6-40",
            "value": 40
          },
          {
            "id": "c7-55",
            "value": 55
          },
          {
            "id": "c8-63",
            "value": 63
          },
          {
            "id": "c9-77",
            "value": 77
          },
          {
            "id": "c10-82",
            "value": 82
          },
          {
            "id": "c11-91",
            "value": 91
          }
        ],
        "pointers": [
          {
            "name": "low",
            "index": 6
          },
          {
            "name": "high",
            "index": 11
          }
        ],
        "highlights": [
          {
            "index": 0,
            "role": "discarded"
          },
          {
            "index": 1,
            "role": "discarded"
          },
          {
            "index": 2,
            "role": "discarded"
          },
          {
            "index": 3,
            "role": "discarded"
          },
          {
            "index": 4,
            "role": "discarded"
          },
          {
            "index": 5,
            "role": "discarded"
          }
        ],
        "codeLine": 7,
        "variables": {
          "low": 6,
          "high": 11,
          "discarded": 6
        },
        "explanation": "31 is too small, and everything to its left is even smaller. 6 boxes are gone in one move — without ever looking at them.",
        "stats": {
          "comparisons": 1,
          "swaps": 0
        }
      },
      {
        "data": [
          {
            "id": "c0-3",
            "value": 3
          },
          {
            "id": "c1-7",
            "value": 7
          },
          {
            "id": "c2-12",
            "value": 12
          },
          {
            "id": "c3-18",
            "value": 18
          },
          {
            "id": "c4-24",
            "value": 24
          },
          {
            "id": "c5-31",
            "value": 31
          },
          {
            "id": "c6-40",
            "value": 40
          },
          {
            "id": "c7-55",
            "value": 55
          },
          {
            "id": "c8-63",
            "value": 63
          },
          {
            "id": "c9-77",
            "value": 77
          },
          {
            "id": "c10-82",
            "value": 82
          },
          {
            "id": "c11-91",
            "value": 91
          }
        ],
        "pointers": [
          {
            "name": "low",
            "index": 6
          },
          {
            "name": "mid",
            "index": 8
          },
          {
            "name": "high",
            "index": 11
          }
        ],
        "highlights": [
          {
            "index": 8,
            "role": "active"
          },
          {
            "index": 0,
            "role": "discarded"
          },
          {
            "index": 1,
            "role": "discarded"
          },
          {
            "index": 2,
            "role": "discarded"
          },
          {
            "index": 3,
            "role": "discarded"
          },
          {
            "index": 4,
            "role": "discarded"
          },
          {
            "index": 5,
            "role": "discarded"
          }
        ],
        "codeLine": 5,
        "variables": {
          "low": 6,
          "mid": 8,
          "high": 11,
          "window": 6
        },
        "explanation": "6 boxes left in the window. Look at the middle one: position 8, holding 63.",
        "stats": {
          "comparisons": 1,
          "swaps": 0
        }
      },
      {
        "data": [
          {
            "id": "c0-3",
            "value": 3
          },
          {
            "id": "c1-7",
            "value": 7
          },
          {
            "id": "c2-12",
            "value": 12
          },
          {
            "id": "c3-18",
            "value": 18
          },
          {
            "id": "c4-24",
            "value": 24
          },
          {
            "id": "c5-31",
            "value": 31
          },
          {
            "id": "c6-40",
            "value": 40
          },
          {
            "id": "c7-55",
            "value": 55
          },
          {
            "id": "c8-63",
            "value": 63
          },
          {
            "id": "c9-77",
            "value": 77
          },
          {
            "id": "c10-82",
            "value": 82
          },
          {
            "id": "c11-91",
            "value": 91
          }
        ],
        "pointers": [
          {
            "name": "mid",
            "index": 8
          }
        ],
        "highlights": [
          {
            "index": 8,
            "role": "found"
          },
          {
            "index": 0,
            "role": "discarded"
          },
          {
            "index": 1,
            "role": "discarded"
          },
          {
            "index": 2,
            "role": "discarded"
          },
          {
            "index": 3,
            "role": "discarded"
          },
          {
            "index": 4,
            "role": "discarded"
          },
          {
            "index": 5,
            "role": "discarded"
          }
        ],
        "codeLine": 6,
        "variables": {
          "result": 8,
          "checked": 2
        },
        "explanation": "63 is exactly what we wanted. Found at index 8 after only 2 looks.",
        "stats": {
          "comparisons": 2,
          "swaps": 0
        }
      }
    ]
  }
}