二分查找
题目描述:
请实现有重复数字的升序数组的二分查找
给定一个 元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的第一个出现的target,如果目标值存在返回下标,否则返回 -1。
示例1:
输入:
[1,2,4,4,5],4
返回值:
2
说明:
从左到右,查找到第1个为4的,下标为2,返回2
示例2:
输入:
[1,2,4,4,5],3
返回值:
-1
要解决这一题我们要先学会二分查找,二分查找有两种方法,其一是递归法,二是非递归法。这里就不详述,如果不会二分查找可以自己查一下资料,这里附上二分查找代码。
C++非递归法:
/**
* left 集合要查找范围的最左边索引
* right 集合要查找范围的最右边做因
* target 我们要查找的数
* nums 我们要查找的集合
*/
int binarySearch(vector<int> nums, int target)
{
int left = 0;
int right = nums.size();
while (left <= right)
{
int mid = left + (right - left) / 2;
if (target > nums[mid])
{
left = mid + 1;
}
else if (target < nums[mid])
{
right = mid - 1;
}
else
{
//找到结果后返回
return mid;
}
}
}
C++非递归法:
/**
* left 集合要查找范围的最左边索引
* right 集合要查找范围的最右边做因
* target 我们要查找的数
* nums 我们要查找的集合
*/
int search(vector<int> nums, int left, int right, int target)
{
if (left >right)
return -1;
int mid=left+(right-left)/2;
if(target>nums[mid])
return search(nums,mid+1,right,target);
else if(target<nums[mid])
return search(nums,left,mid-1,target);
else
return mid;
}
int binarySearch(vector<int> nums, int target)
{
return s(nums, 0, nums.size() - 1, target);
}
上面的代码只能帮助我们找到查找数在集合中位置的索引,但是题目要求的是我们要找到查找数在集合中第一次出现的索引。索引我们就需要对上面的代码做一些改进。
思路:当我们找查找值所在集合中的索引时先不要返回此索引,我们继续在此索引的左边继续查找,下面请看代码。
C++非递归法:
/**
* left 集合要查找范围的最左边索引
* right 集合要查找范围的最右边做因
* result 记录下我们查找数的索引
* target 我们要查找的数
* nums 我们要查找的集合
*/
int search(vector<int>& nums, int target) {
// write code here
int left=0;
int right=nums.size()-1;
int result=-1;
while(left<=right)
{
int mid=left+(right-left)/2;
if(nums[mid]==target)
{
//当查找到结果时不要返回,记录下当前位置,继续向左边查找
result=mid;
right=mid-1;
}
else if(nums[mid]>target)
{
right=mid-1;
}
else
{
left=mid+1;
}
}
return result;
}
C++递归法:
/**
* left 集合要查找范围的最左边索引
* right 集合要查找范围的最右边做因
* result 记录下我们查找数的索引
* target 我们要查找的数
* nums 我们要查找的集合
*/
int search(vector<int> nums, int left, int right,int result, int target)
{
if ( left > right )
return result;
int mid = left + ( right - left ) / 2;
if ( target > nums [mid] )
return search ( nums, mid + 1, right, result, target );
else if ( target < nums [mid] )
return search ( nums, left, mid - 1, result, target );
else
{
result = mid;
//找到值以后记录下来
return search ( nums, left, mid - 1, result, target );
}
}
int binarySearch(vector<int> nums, int target)
{
return s(nums, 0, nums.size() - 1,-1, target);
}
好了,以上就是这道题的题解,如果你有更好的方法欢迎在评论区留言告诉我。我是小王,一名大二计算机专业在读生。我今天要立一个flag,每天更新一道算法题!!!