待定
1.二分法查找的前提:有序
1.二分法查找元素
例题1--287. 寻找重复数,给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。
int findDuplicate(vector<int>& nums) {
int n=nums.size();
int left=0,right=n-1;
int cnt=0;
while(left<right){
int mid=(right-left)/2+left;
cnt=0;
for(auto it:nums){
if(it<=mid){
cnt++;
}
}
if(cnt>mid){
right=mid;
}
else{
left=mid+1;
}
}
return left;
}
例题2--剑指 Offer 53 - II. 0~n-1中缺失的数字 ,一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。
基本思路:二分法查找,但是该问题的实质是:找到nums[mid]!=mid的第一个元素
- 根据nums[i]?i,可以将数组分为A和B两个部分,其中A[i]=i,B[i]!=i,那么最后,i指向B的第一个元素,而j指向A的最后一个元素。
int missingNumber(vector<int>& nums) {
int l=0,r=nums.size()-1;
while(l<=r){
int mid=(r-l)/2+l;
if(mid==nums[mid]){
l=mid+1;
}
else{
r=mid-1;
}
}
return l;
}
2.二分法查找边界
例题1--34. 在排序数组中查找元素的第一个和最后一个位置
- 使用nums[mid]>=target,得到最左边的
- 使用nums[mid]>target,得到最右边的
int binarySearch(vector<int> &nums,int target,bool lower){
int left=0,right=nums.size()-1;
int ans=nums.size(); //防止在target正好是最后一个元素。
while(left<=right){
int mid=(left+right)>>1;
if(nums[mid]>target||(lower&&nums[mid]>=target)){
right=mid-1;
ans=mid;
}
else{
left=mid+1;
}
}
return ans;
}