Linear Scan
Time O(n)Space O(1)The obvious approach: check every element until you find the target. Itβs correct, but it completely ignores the one piece of extra information the problem hands you for free β the array is sorted β which is exactly what the O(log n) requirement is hinting you should exploit.
class Solution: def search(self, nums: list[int], target: int) -> int: for i, num in enumerate(nums): if num == target: return i return -1Binary Search
OptimalTime O(log n)Space O(1)Because the array is sorted, checking the middle element tells you which half the target must be in (if itβs present at all) β so you can discard the other half entirely, every time. Repeat on the shrinking window until you find the target or the window is empty.
class Solution: def search(self, nums: list[int], target: int) -> int: lo, hi = 0, len(nums) - 1 while lo <= hi: mid = (lo + hi) // 2 if nums[mid] == target: return mid elif nums[mid] < target: lo = mid + 1 else: hi = mid - 1 return -1Tracing nums = [-1,0,3,5,9,12], target = 9:
mid=2 β nums[2]=3 < 9, target is to the right. Discard indices 0-2, set lo = mid+1.
Why itβs correct: sortedness guarantees that if nums[mid] < target, every index β€ mid is also < target and can be safely discarded (symmetric argument for >). No valid answer is ever thrown away. Complexity: the search window halves every iteration, so after k steps only n / 2^k elements remain β reaching a single element takes k = logβ n steps β O(log n) time, O(1) space.