35. Search Insert Position
On LeetCode ->Reformulated question¶
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 this question 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.
Solve the problem with idiomatic Python¶
class Solution:
def searchInsert(self, nums: list[int], target: int) -> int:
# Closed interval binary search on [left, right].
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] < target:
left = mid + 1
else:
# Keep mid as a candidate answer.
right = mid - 1
# left is the first index with nums[i] >= target,
# or len(nums) if target is larger than all elements.
return left
from bisect import bisect_left
class SolutionBisect:
def searchInsert(self, nums: list[int], target: int) -> int:
return bisect_left(nums, target)
Pytest test¶
import pytest
@pytest.mark.parametrize(
"nums, target, expected",
[
([1, 3, 5, 6], 5, 2),
([1, 3, 5, 6], 2, 1),
([1, 3, 5, 6], 7, 4),
([1, 3, 5, 6], 0, 0),
([1], 1, 0),
([1], 0, 0),
([1], 2, 1),
([1, 3], 2, 1),
([1, 3, 5], 4, 2),
([1, 3, 5], 6, 3),
],
)
def test_search_insert(nums, target, expected):
assert Solution().searchInsert(nums, target) == expected
Comment 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