1. 题目链接:704. 二分查找
2. 题目描述:
给定一个
n
个元素有序的(升序)整型数组nums
和一个目标值target
,写一个函数搜索nums
中的target
,如果目标值存在返回下标,否则返回-1
。示例 1:
输入: nums = [-1,0,3,5,9,12], target = 9 输出: 4 解释: 9 出现在 nums 中并且下标为 4
示例 2:
输入: nums = [-1,0,3,5,9,12], target = 2 输出: -1 解释: 2 不存在 nums 中因此返回 -1
提示:
- 你可以假设
nums
中的所有元素是不重复的。n
将在[1, 10000]
之间。nums
的每个元素都将在[-9999, 9999]
之间。
3. 算法思路:
-
初始化左指针
left
为0,右指针right
为数组长度减1。 -
进行循环,直到左指针
left
大于右指针right
:a. 计算中间位置
mid
,即(left + right) / 2
。b. 如果中间位置的元素等于目标元素,返回
mid
。c. 如果中间位置的元素大于目标元素,说明目标元素可能在左半部分,将右指针
right
更新为mid - 1
。d. 如果中间位置的元素小于目标元素,说明目标元素可能在右半部分,将左指针
left
更新为mid + 1
。 -
如果循环结束仍未找到目标元素,返回-1。
4. 算法流程:
- 定义
left
,right
指针,分别指向数组的左右区间 - 找到待查找区间的中间点mid,找到之后分三种情况讨论:
arr[mid]==target
,说明正好找到,返回mid的值arr[mid]>target
,说明[mid,right]
这段区间都是大于target
的,因此舍去右边区间,在左边[left,mid-1]
的区间继续查找,即让right=mid-1
,然后重复2
过程;arr[mid]<target
,说明[left,mid]
这段区间的值都小于target
的,因此舍去左边区间,在右边[mid+1,right]
区间继续继续查找,即让left=mid+1
,然后重复2过程
- 当
left
与right·
错开时,说明整个区间都没有这个数,返回-1
5. C++代码实现:
class Solution {
public:
int search(vector<int>& nums, int target)
{
//初始化lef和right指针
int left=0,right=nums.size()-1;
//两个指针相交时,当前元素还未判断,因此需要取等号
while(left<=right)
{
//先找到区间的中间元素
int mid=left+(right-left)/2;
//分三种情况讨论
if(nums[mid]==target) return mid;
else if(nums[mid]>target) right=mid-1;
else left=mid+1;
}
//如果程序走到这里,说明没有找到目标值,返回-1
return -1;
}
};