思路:
1. 二分查找的边界调整逻辑
在二分查找过程中,left
和 right
指针不断调整,将搜索范围缩小到目标值可能存在的区间。具体规则如下:
- 若中间值
nums[mid]
小于 目标值target
,说明目标值在右半区,需将left
移动到mid + 1
; - 若中间值
nums[mid]
大于 目标值target
,说明目标值在左半区,需将right
移动到mid - 1
; - 若相等,直接返回
mid
。
关键点:循环结束时,left
和 right
指针的关系满足 left > right
,此时搜索区间已完全闭合。
2. 循环结束时的指针状态
当循环终止时(即 left > right
):
- 所有小于
target
的元素:均位于left
指针左侧; - 所有大于
target
的元素:均位于left
指针右侧; - 插入位置:
left
指针指向第一个大于target
的元素位置,而right
指针指向最后一个小于target
的元素位置。
示例:数组 [1, 3, 5, 6]
中查找 target = 2
:
- 第一次循环:
mid = 1
(值3
),因3 > 2
,right
移动到0
; - 第二次循环:
left = 0
,right = 0
,mid = 0
(值1
),因1 < 2
,left
移动到1
; - 循环结束,
left = 1
,即插入位置为索引1
(正确结果)。
3. 数学归纳与指针行为
- 最后一次循环的两种情况:
- 数组中剩一个元素:
left == right == mid
。若nums[mid] < target
,left
移动到mid + 1
,此时left
即为插入位置;若nums[mid] > target
,right
移动到mid - 1
,left
仍指向插入位置。 - 数组中剩两个元素:通过调整后,最终仍会收敛到上述逻辑。
- 数组中剩一个元素:
本质:无论目标值是否存在于数组中,left
始终指向第一个大于 target
的位置,而 right
指向最后一个小于 target
的位置。因此,插入位置应为 left
。
4. 时间复杂度与正确性
- 时间复杂度:
O(log n)
,每次循环将搜索范围减半
。 - 正确性保证:通过边界调整和指针移动,
left
最终指向的位置满足有序数组插入后仍保持升序
。
总结
left
指针的最终位置反映了以下性质:
- 所有左侧元素 ≤ target;
- 所有右侧元素 ≥ target。