二分查找
有三种写法:闭区间、半开半闭区间、开区间,本质相同。
以闭区间为例:
- 初始条件:0,n-1
- 循环条件:区间不为空,即left <= right
- 更新逻辑:mid已判断,更新后越过mid
- 返回值:循环内部相等则返回mid,出循环说明没找到,返回-1
搜索插入位置
注意读题:无重复元素。
- 如果找到了目标值,即返回索引,与【二分查找】相同。
- 如果没有找到,返回应该被插入的位置,即大于target的第一个数对应的index,可能大于n-1。
- 考虑跳出循环的前一步,left和right一定重合。
- 此时,left左边都小于目标值,right右边都大于目标值。
- 如果mid小于目标值,left后移,target应该插入在left;反之,right前移,target仍然应该插入left。
- 因此,返回left即可。
在排序数组中查找元素的第一个和最后一个位置
基于【搜索插入位置】,搜索target - 0.5和target + 0.5对应的插入位置即可。
注意:
- target+0.5对应位置需要-1。
- 先搜索一边,如果符合条件(==target),才继续搜索,否则直接返回-1。
- 注意搜索时可能超出边界。
- 始终记住先判断边界条件:nums是否为空。
搜索旋转排序数组
首先,理解二分搜索的判断,虽然简化为了mid和target的比较,但本质上是mid的左区间和右区间,分别与target比较。(因此,其实存在提前终止的优化空间。)
因此,在本题中,问题变为,每次迭代如何确定target在哪个区间?
- 只有有序数组可以直接计算区间范围。 因此,需要先判断左右区间哪一个有序。
- 旋转后,左右区间其一必然有序。
- 如何判断?首末元素比较大小,注意不需要严格大于,因为可能只有一个元素。 接下来,target和有序区间比较,如果不在此区间,则在另一区间。