问题:给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
解析
标签:二分查找
过程:
- 设定左右指针
- 找出中间位置,并判断该位置值是否等于 target
- nums[mid] == target 则返回该位置下标
- nums[mid] > target 则右侧指针移到中间
- nums[mid] < target 则左侧指针移到中间
复杂度分析
- 时间复杂度:O(logN)
- 空间复杂度:O(1)。
代码实现:
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while(left <= right){
int mid = left + (right - left) / 2;
if(nums[mid] > target){
right = mid - 1;
} else if(nums[mid] < target){
left = mid + 1;
} else {
return mid;
}
}
return -1;
}
问题回答:
- 解释一下 int mid = left + (right - left) / 2; 这样写的好处吗?为什么不直接写pivot = (right + left) / 2
假如right
和left
都是一个很大的数,那么right + left
会溢出,而left + (right - left) / 2
先做减法不会溢出。 所以好处是让 mid 变量避免溢出。
(right + left) / 2 = ((right - left) + left + left) / 2 = ((right - left) + 2left) / 2 = left+ (right - left)/2
- 是一种递归方式的查询