实现有重复数字的升序数组的二分查找
题目描述:给定一个 元素有序的(升序且有相同元素)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标(这里指第一个等于目标值的下标),否则返回 -1。
题目分析:这道题和标准二分的差别是数组元素有重复,且需要找到第一个等于目标值的元素的下标。
提供一版正确的代码:
class Solution { public: /** * 如果目标值存在返回下标,否则返回 -1 * @param nums int整型vector * @param target int整型 * @return int整型 */ int search(vector<int>& nums, int target) { int start = 0, end = nums.size() - 1; if (start > end || nums[start] > target || nums[end] < target) //边界检测 return -1; while (start <= end) { int mid = (start + end) / 2; if (nums[mid] > target)//大于的情况 { end = mid - 1; } else if (nums[mid] < target)//小于的情况 start = mid + 1; else// 等于的情况 { if (mid == 0 || nums[mid - 1] != target)//注意先判mid==0,若不成立,再判后面条件,nums[mid-1]才不会 越界 return mid; else end = mid - 1; } } return -1; } };
这里还有一版错的代码,但是在某平台上提交也通过了,不知道后台的case是咋跑的。
class Solution { public: /** * 如果目标值存在返回下标,否则返回 -1 * @param nums int整型vector * @param target int整型 * @return int整型 */ int search(vector<int>& nums, int target) { int start=0,end=nums.size()-1; if(start > end || nums[start] > target || nums[end] < target) //边界检测 return -1; while(start<=end) { int mid=(start+end)/2; if(nums[mid]>=target) { if(mid==0 && nums[mid] > target)//处理只有一个元素且比目标值大的情况 return -1; else if(mid==0 || nums[mid-1]<target)//这里 nums[mid-1]<target 满足但不能保证 nums[mid]==target,还存在大于的情况,所以认为是错的 return mid; else end=mid-1; } else //nums[mid]<target start=mid+1; } return -1; } };