二分查找
二分查找——红蓝染色法
nums = [11, 13, 15, 17]
index -1, 0, 1, 2, 3, 4
原则:
“原本想要处理的,等价于闭区间”;
“结束的原则是区间内没有元素”;
“答案是(L or R)排在后面的那个”。
二分查找的关键是区间定义和结束条件。常见两种写法:
- 闭区间
[0, len-1]- 循环条件:
left <= right - 结束时:
right + 1 == left - 返回:
left
- 循环条件:
- 开区间
(-1, len)- 循环条件:
left + 1 < right - 结束时:
left + 1 == right - 返回:
right
- 循环条件:
34. 在排序数组中查找元素的第一个和最后一个位置
已解答
中等
给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。
示例 1:
输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]
示例 2:
输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]
示例 3:
输入:nums = [], target = 0
输出:[-1,-1]
提示:
0 <= nums.length <= 105-109 <= nums[i] <= 109nums是一个非递减数组-109 <= target <= 109
分析
二分查找原本是在有序数组里查找到目标值,那么第一个元素恰好就是“二分查找”可以查到的。关键是最后一个元素怎么查到?这里涉及到几种搭配,>=, >, <, <=。二分查找是>=,第二个元素可以转化为>=target+1,然后求出的index-1,即找到第一个大于target+1的元素,他的前一个就是这“第二个”元素;注意需要先判断第一个元素的索引是否存在。
利用二分查找找到第一个 ≥ target 的位置(即 lowerBound);
再找到第一个 ≥ target+1 的位置,减 1 即为最后一个等于 target 的位置;
注意检查 target 是否存在。
func lowerBound(nums []int, target int) int {
//寻找有序数组里,第一个>= target的数字
//开区间写法(-1,len)===> (L,R)
left := -1
right := len(nums)
for left+1 < right

最低0.47元/天 解锁文章
1820

被折叠的 条评论
为什么被折叠?



