Search Insert Position in Sorted Array (Lower Bound Approach)
Problem and examples
Given a sorted array of distinct integers and a target number x, your task is to find the insert position of x.
This means you must return the index where x is located in the array. If it is not present, return the index where it should be inserted in order to keep the array sorted.
This problem is also known as finding the lower bound — the first index where an element is greater than or equal to x.
| Input Array | Target (x) | Insert Position | Description |
|---|---|---|---|
| [10, 20, 30, 40, 50] | 35 | 3 | 35 should be inserted before 40 |
| [10, 20, 30, 40, 50] | 20 | 1 | Exact match at index 1 |
| [10, 20, 30, 40, 50] | 5 | 0 | Smaller than all elements, inserted at beginning |
| [10, 20, 30, 40, 50] | 55 | 5 | Larger than all elements, inserted at end |
| [5, 15, 25, 35] | 25 | 2 | Exact match at index 2 |
| [5] | 2 | 0 | Inserted before the only element |
| [5] | 5 | 0 | Exact match at index 0 |
| [5] | 8 | 1 | Inserted after the only element |
Explore Search Insert Position in Sorted Array - Lower Bound Binary Search
Load an example or enter your own input. Use the player controls to follow each change.
Understanding the Problem
Suppose you are given a sorted array, and you want to find the correct position to insert a target number x so that the array remains sorted. This problem is not just about checking if x is present; it's about finding the position where it could be inserted — this is called the lower bound.
For example, if arr = [1, 3, 5, 6] and x = 5, the output should be 2 because 5 is already at index 2.
But if x = 4, then the correct insert position is 2 because it would go between 3 and 5.
Step-by-Step Intuition
Let’s solve this using a technique called binary search, which is perfect for sorted arrays. Instead of checking every position one by one, we’ll divide the array in halves, zero in on the region where x could go, and find the first index where arr[i] ≥ x.
Step 1: Initialize Search Range
We start with two pointers:
low = 0(start of the array)high = n - 1(end of the array)
We also define ans = n (default answer is the end of array, in case x is greater than all elements).
Step 2: Binary Search Loop
Repeat while low ≤ high:
- Calculate
mid = Math.floor((low + high) / 2) - If
arr[mid] ≥ x:- This index might be the correct insert position, so set
ans = mid - Move search to the left half:
high = mid - 1
- This index might be the correct insert position, so set
- Else:
xis greater thanarr[mid], so move right:low = mid + 1
Step 3: Final Answer
After the loop ends, ans will hold the first index where x can be inserted to maintain the sorted order.
Example Walkthrough
Let’s try with arr = [1, 3, 5, 6] and x = 4.
low = 0,high = 3mid = 1→arr[1] = 3→ 3 < 4 → move right →low = 2mid = 2→arr[2] = 5→ 5 ≥ 4 →ans = 2,high = 1- Loop ends → Final answer:
2
Handling Edge Cases
- x is smaller than all elements → e.g.,
x = 0→ insert at index0 - x is greater than all elements → e.g.,
x = 10→ insert at indexarr.length - x is equal to an existing value → insert at the first occurrence (lower bound)
Why Binary Search?
Binary search gives us an efficient way to solve this in O(log n) time instead of scanning every element. This is especially useful for large arrays.
- Given a sorted array
arrof distinct integers and a target valuex. - Initialize:
low = 0,high = arr.length - 1,ans = arr.length. - While
low ≤ high: - → Compute
mid = Math.floor((low + high) / 2). - → If
arr[mid] ≥ x, updateans = midand move left:high = mid - 1. - → Else, move right:
low = mid + 1. - Return
ansas the correct insert position.
Implementation and efficiency
C implementation
#include <stdio.h>
int searchInsertPosition(int arr[], int size, int target) {
int low = 0, high = size - 1, ans = size;
while (low <= high) {
int mid = low + (high - low) / 2;
if (arr[mid] >= target) {
ans = mid;
high = mid - 1;
} else {
low = mid + 1;
}
}
return ans;
}
int main() {
int arr[] = {1, 3, 5, 6};
int size = sizeof(arr) / sizeof(arr[0]);
int target = 2;
printf("Insert Position: %d\n", searchInsertPosition(arr, size, target));
return 0;
}C++ implementation
#include <iostream>
#include <vector>
using namespace std;
int searchInsertPosition(vector<int>& arr, int target) {
int low = 0, high = arr.size() - 1, ans = arr.size();
while (low <= high) {
int mid = low + (high - low) / 2;
if (arr[mid] >= target) {
ans = mid;
high = mid - 1;
} else {
low = mid + 1;
}
}
return ans;
}
int main() {
vector<int> arr = {1, 3, 5, 6};
int target = 2;
cout << "Insert Position: " << searchInsertPosition(arr, target) << endl;
return 0;
}Python implementation
def search_insert_position(arr, x):
n = len(arr)
low, high = 0, n - 1
ans = n
while low <= high:
mid = (low + high) // 2
if arr[mid] >= x:
ans = mid
high = mid - 1
else:
low = mid + 1
return ans
# Sample Input
arr = [1, 3, 5, 6]
target = 2
print("Insert Position:", search_insert_position(arr, target))Java implementation
public class SearchInsertPosition {
public static int searchInsert(int[] arr, int target) {
int low = 0, high = arr.length - 1, ans = arr.length;
while (low <= high) {
int mid = (low + high) / 2;
if (arr[mid] >= target) {
ans = mid;
high = mid - 1;
} else {
low = mid + 1;
}
}
return ans;
}
public static void main(String[] args) {
int[] arr = {1, 3, 5, 6};
int target = 2;
System.out.println("Insert Position: " + searchInsert(arr, target));
}
}JavaScript implementation
function searchInsertPosition(arr, target) {
let low = 0, high = arr.length - 1;
let ans = arr.length;
while (low <= high) {
const mid = Math.floor((low + high) / 2);
if (arr[mid] >= target) {
ans = mid;
high = mid - 1;
} else {
low = mid + 1;
}
}
return ans;
}
// Sample Input
const arr = [1, 3, 5, 6];
const target = 2;
console.log("Insert Position:", searchInsertPosition(arr, target));Go implementation
package main
import (
"fmt"
)
func searchInsertPosition(arr []int, target int) int {
low, high := 0, len(arr)-1
ans := len(arr)
for low <= high {
mid := (low + high) / 2
if arr[mid] >= target {
ans = mid
high = mid - 1
} else {
low = mid + 1
}
}
return ans
}
func main() {
arr := []int{1, 3, 5, 6}
target := 2
fmt.Println("Insert Position:", searchInsertPosition(arr, target))
}Rust implementation
fn search_insert_position(arr: &Vec<i32>, target: i32) -> usize {
let (mut low, mut high) = (0, arr.len() as i32 - 1);
let mut ans = arr.len();
while low <= high {
let mid = low + (high - low) / 2;
if arr[mid as usize] >= target {
ans = mid as usize;
high = mid - 1;
} else {
low = mid + 1;
}
}
ans
}
fn main() {
let arr = vec![1, 3, 5, 6];
let target = 2;
println!("Insert Position: {}", search_insert_position(&arr, target));
}Kotlin implementation
fun searchInsertPosition(arr: IntArray, target: Int): Int {
var low = 0
var high = arr.size - 1
var ans = arr.size
while (low <= high) {
val mid = (low + high) / 2
if (arr[mid] >= target) {
ans = mid
high = mid - 1
} else {
low = mid + 1
}
}
return ans
}
fun main() {
val arr = intArrayOf(1, 3, 5, 6)
val target = 2
println("Insert Position: ${searchInsertPosition(arr, target)}")
}Swift implementation
func searchInsertPosition(_ arr: [Int], _ target: Int) -> Int {
var low = 0, high = arr.count - 1
var ans = arr.count
while low <= high {
let mid = (low + high) / 2
if arr[mid] >= target {
ans = mid
high = mid - 1
} else {
low = mid + 1
}
}
return ans
}
let arr = [1, 3, 5, 6]
let target = 2
print("Insert Position:", searchInsertPosition(arr, target))TypeScript implementation
function searchInsertPosition(arr: number[], target: number): number {
let low = 0, high = arr.length - 1;
let ans = arr.length;
while (low <= high) {
const mid = Math.floor((low + high) / 2);
if (arr[mid] >= target) {
ans = mid;
high = mid - 1;
} else {
low = mid + 1;
}
}
return ans;
}
const arr: number[] = [1, 3, 5, 6];
const target: number = 2;
console.log("Insert Position:", searchInsertPosition(arr, target));Time complexity
| Case | Time | Explanation |
|---|---|---|
| best case | O(1) | The target is found at the middle index on the first comparison, requiring only one iteration. |
| average case | O(log n) | Binary search halves the search space in each iteration, so on average, it takes log n steps to find the insert position. |
| worst case | O(log n) | In the worst case, the entire array must be searched logarithmically to determine where the target should be inserted. |
Space complexity
O(1)
The algorithm operates in-place using only a constant amount of memory — just a few integer variables for low, high, mid, and ans.