35. Search Insert Position
On LeetCode ->Problem¶
Given a sorted array of distinct integers, return the index of target, or the index where it should be inserted to keep the array sorted, in \(O(\log n)\).
- Example:
nums=[1,3,5,6], target=2 -> 12is not present- inserting at index
1gives[1,2,3,5,6]
Key trick¶
Use binary search for the first index where nums[i] >= target.
- If
targetexists, that index is its position. - If not, that index is exactly the insertion position.
- After the loop,
leftis the answer.
Trap¶
- Using
right = len(nums)but then readingnums[mid]carelessly. - Returning a temporary
indexvariable instead of the final binary-search boundary. - Updating bounds incorrectly:
- for
target < nums[mid], useright = mid - 1in closed interval search - or
right = midin half-open interval search
- for
- Forgetting edge cases:
- insert at start
- insert at end
- single-element array
Why is it interesting?¶
It is a small binary-search problem where correctness depends on choosing and keeping one invariant.
- It tests whether you really understand boundaries.
- It is also the "lower bound" pattern, reused in many harder problems.
Python solution¶
import bisect
class Solution:
def searchInsert(self, nums: list[int], target: int) -> int:
# Closed interval binary search on [l, r].
l, r = 0, len(nums) - 1
while l <= r:
mid = (l + r) // 2
if nums[mid] < target:
l = mid + 1
else:
# Keep mid as a candidate answer.
r = mid - 1
# l is the first index with nums[i] >= target,
# or len(nums) if target is larger than all elements.
return l
def searchInsert_2(self, nums: list[int], target: int) -> int:
return bisect.bisect_left(nums, target)
Comment on my solution¶
Your code is close, but the interval logic is inconsistent.
- You start with a half-open range:
left, right = 0, len(nums)
- But your updates do not match that pattern:
right = mid + 1should not happen when going left- that can keep the range wrong or stuck
indexis not reliable:- it may be uninitialized if the loop never runs
- it is better to return
left
- For this problem, the simplest correct invariant is:
- keep searching while
left <= right - move
leftright whennums[mid] < target - otherwise move
rightleft - return
left
- keep searching while
# WRONG
class Solution:
def searchInsert(self, nums: list[int], target: int) -> int:
left, right = 0, len(nums)
while left < right:
mid = (right + left) // 2
if target == nums[mid]:
return mid
if target < nums[mid]:
index = mid - 1
right = mid + 1
else:
index = mid + 1
left = mid + 1
return index
# WRONG (tried later - 2026-07-28)
# I starts to have more clarity about binary search
class Solution:
def searchInsert(self, nums: list[int], target: int) -> int:
left, right = 0, len(nums) - 1
while left < right:
mid = (left + right) // 2
if nums[mid] < target:
left = mid + 1
else:
right = mid
return left
Solution().searchInsert([1], 2) # returns 0 but it should be 1
Solution().searchInsert([1, 3, 5, 6], 7) # returns 3 but it should be 4