Facebook Pixel

35. Search Insert Position

Problem Description

You are given a sorted array of distinct integers and a target value. Your task is to find where the target value should be placed in the array to maintain the sorted order.

If the target value already exists in the array, return its index. If the target value doesn't exist, return the index where it would be inserted to keep the array sorted.

For example:

  • If nums = [1, 3, 5, 6] and target = 5, the function should return 2 because 5 exists at index 2
  • If nums = [1, 3, 5, 6] and target = 2, the function should return 1 because 2 would be inserted at index 1 to maintain sorted order
  • If nums = [1, 3, 5, 6] and target = 7, the function should return 4 because 7 would be inserted at the end

The algorithm must have O(log n) runtime complexity, which means you need to use binary search rather than a linear scan through the array.

The solution uses binary search to efficiently find the insertion position. It maintains two pointers l (left) and r (right) to define the search range. In each iteration, it calculates the middle index and compares nums[mid] with the target. If nums[mid] >= target, it means the target should be inserted at or before the middle position, so the search continues in the left half. Otherwise, the search continues in the right half. When the loop ends, l points to the correct insertion position.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

Since we need O(log n) complexity and the array is sorted, binary search is the natural choice. We're looking for the first position where we could insert the target to maintain sorted order.

This is a classic boundary-finding problem. Think of the array as having a boolean pattern:

  • false for all indices where nums[i] < target
  • true for all indices where nums[i] >= target

The pattern looks like: false, false, ..., false, true, true, ..., true

We want to find the first true - the first index where nums[i] >= target. This is exactly what the binary search template finds.

Feasible Function: nums[mid] >= target

Using the template:

  • When nums[mid] >= target, we record mid as a potential answer and search left for an earlier position
  • When nums[mid] < target, the answer must be to the right

By the time our search completes, first_true_index will be:

  • The index of the target if it exists
  • The index where the target should be inserted if it doesn't exist
  • -1 if all elements are smaller than the target (meaning insert at the end)

This approach handles both cases (element exists or doesn't exist) with the same logic.

Learn more about Binary Search patterns.

Solution Implementation

1class Solution:
2    def searchInsert(self, nums: List[int], target: int) -> int:
3        """
4        Find the index where target should be inserted in a sorted array.
5        Uses the binary search template with first_true_index tracking.
6        """
7        n = len(nums)
8        left, right = 0, n - 1
9        first_true_index = -1
10
11        while left <= right:
12            mid = (left + right) // 2
13            if nums[mid] >= target:
14                first_true_index = mid
15                right = mid - 1
16            else:
17                left = mid + 1
18
19        # If first_true_index is -1, all elements are smaller than target
20        # Insert at the end
21        return first_true_index if first_true_index != -1 else n
22
1class Solution {
2    public int searchInsert(int[] nums, int target) {
3        int n = nums.length;
4        int left = 0;
5        int right = n - 1;
6        int firstTrueIndex = -1;
7
8        while (left <= right) {
9            int mid = left + (right - left) / 2;
10
11            if (nums[mid] >= target) {
12                firstTrueIndex = mid;
13                right = mid - 1;
14            } else {
15                left = mid + 1;
16            }
17        }
18
19        // If firstTrueIndex is -1, all elements are smaller than target
20        // Insert at the end
21        return firstTrueIndex != -1 ? firstTrueIndex : n;
22    }
23}
24
1class Solution {
2public:
3    int searchInsert(vector<int>& nums, int target) {
4        int n = nums.size();
5        int left = 0;
6        int right = n - 1;
7        int firstTrueIndex = -1;
8
9        while (left <= right) {
10            int mid = left + (right - left) / 2;
11
12            if (nums[mid] >= target) {
13                firstTrueIndex = mid;
14                right = mid - 1;
15            } else {
16                left = mid + 1;
17            }
18        }
19
20        // If firstTrueIndex is -1, all elements are smaller than target
21        // Insert at the end
22        return firstTrueIndex != -1 ? firstTrueIndex : n;
23    }
24};
25
1/**
2 * Binary search to find the index where target should be inserted in a sorted array.
3 * Uses the binary search template with first_true_index tracking.
4 */
5function searchInsert(nums: number[], target: number): number {
6    const n: number = nums.length;
7    let left: number = 0;
8    let right: number = n - 1;
9    let firstTrueIndex: number = -1;
10
11    while (left <= right) {
12        const mid: number = Math.floor((left + right) / 2);
13
14        if (nums[mid] >= target) {
15            firstTrueIndex = mid;
16            right = mid - 1;
17        } else {
18            left = mid + 1;
19        }
20    }
21
22    // If firstTrueIndex is -1, all elements are smaller than target
23    // Insert at the end
24    return firstTrueIndex !== -1 ? firstTrueIndex : n;
25}
26

Solution Approach

We use the standard binary search template with first_true_index to track the answer.

Template Structure:

left, right = 0, n - 1
first_true_index = -1

while left <= right:
    mid = (left + right) // 2
    if nums[mid] >= target:  # feasible condition
        first_true_index = mid
        right = mid - 1
    else:
        left = mid + 1

return first_true_index if first_true_index != -1 else n

Feasible Condition: nums[mid] >= target

This finds the first index where the element is greater than or equal to the target.

Algorithm Steps:

  1. Initialize left = 0, right = n - 1, and first_true_index = -1

  2. While left <= right:

    • Calculate mid = (left + right) // 2
    • If nums[mid] >= target: record mid as potential answer, search left (right = mid - 1)
    • Else: search right (left = mid + 1)
  3. Return first_true_index if it's not -1, otherwise return n (insert at end)

Why This Works:

  • When nums[mid] >= target, mid could be the insertion point, so we save it and search left for a possibly earlier position
  • When nums[mid] < target, the insertion point must be after mid
  • If first_true_index remains -1, all elements are smaller than target, so insert at the end

Time Complexity: O(log n) - we halve the search space in each iteration Space Complexity: O(1) - only using constant extra space

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through finding the insertion position for target = 4 in the array nums = [1, 3, 5, 7, 9].

Initial State:

  • Array: [1, 3, 5, 7, 9]
  • Target: 4 (doesn't exist, should go between 3 and 5)
  • left = 0, right = 4, first_true_index = -1

Iteration 1:

  • Calculate mid = (0 + 4) // 2 = 2
  • Check nums[2] = 5 >= 4? Yes
  • first_true_index = 2, right = 1

Iteration 2:

  • left = 0, right = 1
  • Calculate mid = (0 + 1) // 2 = 0
  • Check nums[0] = 1 >= 4? No
  • left = 1

Iteration 3:

  • left = 1, right = 1
  • Calculate mid = (1 + 1) // 2 = 1
  • Check nums[1] = 3 >= 4? No
  • left = 2

Termination:

  • Now left = 2, right = 1, so left > right
  • Loop ends
  • Return first_true_index = 2

Verification: Inserting 4 at index 2 gives us [1, 3, 4, 5, 7, 9], which maintains sorted order.

Edge Case Example: Target larger than all elements

For nums = [1, 3, 5] and target = 7:

  • After the search, first_true_index remains -1 (no element >= 7)
  • Return n = 3 (insert at end)

Edge Case Example: Target smaller than all elements

For nums = [3, 5, 7] and target = 1:

  • First iteration: nums[1] = 5 >= 1first_true_index = 1
  • Eventually finds first_true_index = 0
  • Return 0 (insert at beginning)

Time and Space Complexity

Time Complexity: O(log n), where n is the length of the array nums. The algorithm uses the binary search template with while left <= right. In each iteration, either left = mid + 1 or right = mid - 1, halving the search range. Maximum iterations: log₂(n).

Space Complexity: O(1). The algorithm uses only constant extra space for variables (left, right, mid, firstTrueIndex), regardless of input size. No recursive calls or additional data structures.

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Using Wrong Binary Search Template Variant

The Pitfall: Using while left < right with right = mid instead of the standard template with first_true_index tracking.

Example of the Issue:

# Non-standard variant
while left < right:
    mid = (left + right) // 2
    if nums[mid] >= target:
        right = mid
    else:
        left = mid + 1
return left

Solution: Use the standard binary search template with explicit answer tracking:

left, right = 0, n - 1
first_true_index = -1

while left <= right:
    mid = (left + right) // 2
    if nums[mid] >= target:
        first_true_index = mid
        right = mid - 1
    else:
        left = mid + 1

return first_true_index if first_true_index != -1 else n

2. Forgetting to Handle first_true_index = -1

The Pitfall: Not handling the case where all elements are smaller than the target.

Example Scenario:

nums = [1, 3, 5]
target = 7
# first_true_index remains -1, should return 3 (insert at end)

Solution: Always check for -1 and return n:

return first_true_index if first_true_index != -1 else n

3. Integer Overflow in Mid Calculation

The Pitfall: In languages with fixed integer sizes, (left + right) / 2 can overflow.

Solution: Use overflow-safe calculation:

mid = left + (right - left) // 2  # Safe

4. Empty Array Edge Case

The Pitfall: Not handling empty arrays properly.

Solution: The template handles this correctly: when n = 0, right = -1, the loop doesn't execute, and first_true_index = -1, so we return n = 0, which is correct.

Loading...
Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

The three-steps of Depth First Search are:

  1. Identify states;
  2. Draw the state-space tree;
  3. DFS on the state-space tree.

Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More