二分查找
题目:
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。你可以假设 nums 中的所有元素是不重复的。n 将在 [1, 10000]之间。nums 的每个元素都将在 [-9999, 9999]之间。
示例:
示例 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
思想:
- 因为数组有序,定义左边边界为L,右边为R,则mid=(R-L+1)/2+L这样比相加除2好,可以防止溢出。
- 把val和mid比较,如果大于则L=mid+1,小于则R=mid-1。
- 循环不断进行比较,直到L>R,L==R时也需要包含,否则无法判断数组只有一个元素的情况。如果找到则return mid。
- 找不到return -1。
- 两种实现方式,一种利用while循环,一种利用递归。
代码: 循环
int search(vector<int>& nums, int target)
{
if(nums.size()==0)return -1;
int L=0;
int R=nums.size()-1;
while(L<=R)
{
int mid=(R-L+1)/2+L;
if(target>nums[mid])//在右边
{
L=mid+1;
}
else if(target<nums[mid])//在左边
{
R=mid-1;
}
else//相等
return mid;
}
return -1;
}
int main()
{
vector<int> a;
a.push_back(-1);
a.push_back(0);
a.push_back(3);
a.push_back(5);
a.push_back(9);
a.push_back(12);
cout<<search(a,9);
}
递归:
int FindB(vector<int>& nums,int L,int R, int target)
{
int pos=-1;
if(L<=R)
{
int mid=(R-L+1)/2+L;
if(target>nums[mid])//在右边
{
pos=FindB(nums,mid+1,R,target); //不要忘了要有变量接收
}
else if(target<nums[mid])//在左边
{
pos=FindB(nums,L,mid-1,target);
}
else
pos=mid;
}
return pos;
}
int search(vector<int>& nums, int target)
{
if(nums.size()==0)return -1;
else
return FindB(nums,0,nums.size()-1,target);
}
相关应用
面试题53-I. 在排序数组中查找数字
面试题53 - II. 0~n-1中缺失的数字
面试题11. 旋转数组的最小数字
加油哦!🥘