1、求开方
利用二分查找的思想,因为sqrt所在的区间肯定在1~x之间,又有sqrt==x/sqrt,sqrt=x/mid,通过比较sqrt与mid的大小,若mid>sqrt,往mid左边走,若mid较小,mid<sqrt往mid右边走,知道走到一个i的平方<x,i+1的平方>x的位置,此时end<start,跳出循环,end指向较小值,end为所求的值。
class Solution {
public:
int mySqrt(int x) {
if(x<=1)
return x;
int start=1;
int end=x;
while(start<=end){
int mid=start+(end-start)/2;
int sqrt=x/mid;
if(sqrt==mid)
return mid;
else if(mid>sqrt)//mid较大,往左走
end=mid-1;
else
start=mid+1;
}
return end;
}
};
744. Find Smallest Letter Greater Than Target (Easy)
class Solution {
public:
char nextGreatestLetter(vector<char>& letters, char target) {
if(letters.size()<2||target-'a'<0||target-'a'>25)
return letters[0];
int start=0;
int end=letters.size()-1;
while(start<=end){
int mid=start+(end-start)/2;
if(letters[mid]>target)
end=mid-1;
else
start=mid+1;
}
if(start<letters.size())//判断是否越出边界,存在找不到字符的情况,这里需要注意
return letters[start];
else
return letters[0];
}
};
540. Single Element in a Sorted Array (Medium)
思路,通过判断中位数的位置是奇数还是偶数,在容器中,偶数位置的左侧有偶数个数,奇数位置的左侧有奇数个数,由于数组中只有一个数没有成对,所以数组的长度为奇数。若mid为偶数,则左侧有偶数个数,判断mid是否与mid+1成对,若成对,则说明左侧的数都成对,则这个单一元素存在于mid的右侧,start=mid。若不成对,说明包括mid在内的左侧数有单一元素,end=mid;
若mid为奇数位置,则mid左侧有奇数个数,若mid与mid+1成对,则说明mid左侧存在单一元素,end=mid-1;若不成对,则说明mid与mid左侧的数成对,单一元素在右边,start=mid+1;
class Solution {
public:
bool isvalid=true;
int singleNonDuplicate(vector<int>& nums) {
if(nums.empty()){
isvalid=false;
return 0;
}
int start=0;
int end=nums.size()-1;
while(start<end){
int mid=start+(end-start)/2;
if(mid%2==0){
if(nums[mid]==nums[mid+1])
start=mid;
else
end=mid;
}
else
{ if(nums[mid]==nums[mid+1])
end=mid-1;
else
start=mid+1;
}
}
return nums[end];
}
};
4、第一个错误的版本
// Forward declaration of isBadVersion API.
bool isBadVersion(int version);
class Solution {
public:
int firstBadVersion(int n) {
if(n<=0)
return 0;
int start=1;
int end=n;
while(start<end){//end=mid,则循环条件为start<end
int mid=start+(end-start)/2;
if(isBadVersion(mid))
end=mid;//mid也为true,下一次遍历时也要把mid包含进去,mid可能是所求的位置
else
start=mid+1;
}
return start;
}
};
153. Find Minimum in Rotated Sorted Array (Medium)
思路 通过比较mid与end的大小,逐步缩小范围。若mid位置的值大于end上的值,则最小值应该在mid的右侧,start=mid+1;若mid位置的值小于等于end位置上的值,则最小值应在包含mid向左的范围,end=mid;因此循环条件是start<end;
class Solution {
public:
int findMin(vector<int>& nums) {
int start=0;
int end=nums.size()-1;
while(start<end){
int mid=start+(end-start)/2;
if(nums[mid]>nums[end])
start=mid+1;
else
end=mid;
}
return nums[start];
}
};
6、查找区间
34. Search for a Range (Medium)
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
vector<int>res;
int l=0;
int h=nums.size()-1;
while(l<=h){
int mid=l+(h-l)/2;
if(nums[mid]>target)
h=mid-1;
else if(nums[mid]<target)
l=mid+1;
else if(nums[mid]==target){
int flag1=mid;int flag2=mid;
while(flag1>0&&nums[flag1-1]==target)//循环结束条件为mid为最左的target或mid=0
flag1--;
while(flag2<nums.size()-1&&nums[flag2+1]==target)
++flag2;
res.push_back(flag1);
res.push_back(flag2);
return res;
}
}
res.push_back(-1);
res.push_back(-1);
return res;
}
};