思路:
- 时间复杂度要求O(log n),想到二分搜索,这题有一点区别就是返回索引有一点变化。
- 程序写法可以分为首尾索引用while逼近缩小,也可以使用函数递归调用返回写。
- 需要考虑的几个点,left变化,mid计算=left+(right-left)/2 ,小于left,大于right返回的索引,
普通解法1,函数迭代
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int length=nums.size();
if(length==0 )
return 0;
return search(nums,target,0,length-1);
}
int search(vector<int>& nums, int target,int left,int right){
int mid=left+(right-left)/2;
if(target<nums[left])
return left;
else if(target>nums[right])
return right+1;
if(target==nums[mid])
return mid;
else if(target<nums[mid])
return search(nums,target,left,mid-1);
else
return search(nums,target,mid+1,right);
}
};
普通解法2,二分循环
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int left=0;
int right=nums.size()-1;
while(left<=right){
if(target<=nums[left+(right-left)/2])
right=left+(right-left)/2-1;
else
left=left+(right-left)/2+1;
}
return left;
}
};
关于lower_bound( )和upper_bound( )的常见用法
一行程序解法,
return lower_bound(nums.begin(),nums.end(),target) - nums.begin();
lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。