持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第14天,点击查看活动详情
题目描述
难度:简单
给定一个 n 个元素有序的(升序)整型数组 nums
和一个目标值 target
,写一个函数搜索 nums
中的 target
,如果目标值存在返回下标,否则返回 -1
输入:整型数组 nums
、搜索目标值 target
输出:搜索目标值的下标,或者-1。
算法
由题意可知,给定的待搜索数组为有序数组,对于有序数组的搜索,优先考虑二分查找来提高效率。
步骤
二分查找的思想为将整个数组分为两部分来查找,步骤如下:
- 每次拿目标元素与整个搜索区间的中间元素比较;
- 若是目标元素等于中间元素,此时目标已找到,直接返回中间元素的下标;
- 若是目标元素大于中间元素,则说明目标元素在右半搜索区间,此时将区间缩小为右半搜索区间,即区间左指针右移到中间元素的后一元素;(因为中间元素已经被比较过,所以缩小后的搜索区间无需包括中间元素)
- 若是目标元素小于中间元素,则说明目标元素在左半搜索区间,此时将区间缩小为左半搜索区间,即区间右指针左移到中间元素的前一元素;
- 最后若左指针大于右指针,此时区间已不存在,但是还是未找到目标元素,说明目标元素不存在于数组中,返回-1。
注意:边界条件为left = right,此时mid也与这两者重合,还需要最后判断这个边界是否符合条件,所以循环条件为left <= right。
时间复杂度和空间复杂度
时间复杂度:设整个数组的长度,可以看出二分查找的比较次数为m次,又有,所以时间复杂度为。
空间复杂度:只有区间的左右指针两个额外变量,为常数个额外空间,所以空间复杂度为。
代码实现
public int binarySearch(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while(left <= right){
int mid = left + (right - left) / 2;
if(target == nums[mid]){
return mid;
}else if(target < nums[mid]){
right = mid - 1;
}else{
left = mid + 1;
}
}
return -1;
}