Leetcode704
1.问题描述
2.解决方案
二分法总结:
1.有序加无重复—>符合二分的前提条件
2.区间边界的定义很重要
3.其实下面三种方法区间的定义不同就在于while里面的条件时left<right还是left<=right,还有left,right取mid这两点不同,这个根据定义很好想出来的!
4.还有一个代码实现细节,求mid的三种方法,很明显后两种都能避免溢出!
int mid=(begin+end)/2;
int mid=left+((right-left)/2);
int mid=left+((right-left)>>1);
解法一:左闭右闭递归
class Solution {
public:
int find(vector<int>& nums,int begin,int end,int target){
if(begin>end) return -1;
int mid=(begin+end)/2;
if(nums[mid]==target) return mid;
if(nums[mid]>target) return find(nums,begin,mid-1,target);
if(nums[mid]<target) return find(nums,mid+1,end,target);
//会不会从这经过呢?
return -1;
}
int search(vector<int>& nums, int target) {
//int len=nums.size();
//if(len==0) return -1;
return find(nums,0,nums.size()-1,target);
}
};
解法二:左闭右闭迭代
class Solution {
public:
int search(vector<int>& nums, int target) {
int left=0;
int right=nums.size()-1; //左闭右闭
while(left<=right){
int mid=left+((right-left)/2);// 防止溢出 等同于(left + right)/2
if(nums[mid]==target) return mid;
if(nums[mid]<target) left=mid+1;
if(nums[mid]>target) right=mid-1;
}
return -1;
}
};
解法三:左闭右开迭代
class Solution2 {
public:
int search(vector<int>& nums, int target) {
int left=0;
int right=nums.size(); //左闭右开
while(left<right){
//int mid=left+((right-left)/2);// 防止溢出 等同于(left + right)/2
int mid=left+((right-left)>>1);// 防止溢出 等同于(left + right)/2
if(nums[mid]==target) return mid;
if(nums[mid]<target) left=mid+1;
if(nums[mid]>target) right=mid;
}
return -1;
}
};