【LeetCode】35. 搜索插入位置
leetcode
算法思路
-
初始化区间:
采用左闭右闭区间[left, right],初始时left=0,right=len(nums)-1。 -
循环条件:
使用left <= right作为循环条件,确保区间有效性(当left == right时仍需要检查最后一个元素)。 -
中间值计算:
通过middle = left + (right - left)/2计算中间索引,避免整数溢出。 -
分支判断:
- 若
nums[middle] == target:直接返回当前索引 - 若
nums[middle] > target:调整右边界为middle-1(排除右侧区间) - 若
nums[middle] < target:调整左边界为middle+1(排除左侧区间)
- 若
-
插入位置确定:
当循环结束时,left指向第一个大于target的元素位置,即为插入位置。
Golang 实现
func searchInsert(nums []int, target int) int { left, right := 0, len(nums)-1 for left <= right { middle := left + (right - left)/2 // 防止溢出 if nums[middle] == target { return middle } else if nums[middle] > target { right = middle - 1 // 缩小至左区间 } else { left = middle + 1 // 缩小至右区间 } } return left // 未找到时返回插入位置 }
代码解析
- 时间复杂度:O(log n),每次循环排除一半元素,满足题目要求。
- 空间复杂度:O(1),仅使用常量空间存储索引值。
- 边界处理:
- 当
target大于所有元素时,循环结束后left = len(nums),直接返回该值作为插入位置。 - 当
target需要插入数组中间时,left自动指向正确位置(如示例2中的2插入到索引1)。
- 当
示例验证
fmt.Println(searchInsert([]int{1,3,5,6}, 5)) // 2(示例1) fmt.Println(searchInsert([]int{1,3,5,6}, 2)) // 1(示例2) fmt.Println(searchInsert([]int{1,3,5,6}, 7)) // 4(示例3)
关键点总结
- 循环条件选择:左闭右闭区间必须用
left <= right,否则会漏查边界情况。 - 插入位置推导:二分查找结束后,
left的物理意义是「数组中第一个大于target的元素位置」,这个特性天然支持插入位置的确定。 - 溢出保护:通过
left + (right-left)/2代替(left+right)/2,规避大数相加的溢出风险。

浙公网安备 33010602011771号