算法复习:二分查找
leetcode 69. x 的平方根
注意边界条件和判断条件
mid int存不下要用long long
long long mid=lower+(upper-lower)/2 取上界
long long mid=lower+(upper-lower+1)/2 取下界
class Solution { public: int mySqrt(int x) { int lower=1,upper=x; long long mid=lower+(upper-lower)/2; if(x==0) return 0; while(lower<mid) { if(mid*mid==x) return mid; if(mid*mid>x) { upper=mid; mid=lower+(upper-lower)/2; continue; } if(mid*mid<x) { lower=mid; mid=lower+(upper-lower)/2; continue; } } return mid; } };
leetcode 154. 寻找旋转排序数组中的最小值 II 153. 寻找旋转排序数组中的最小值
154和153的区别是数组中可以有重复数字,因此154的代码153可用
思路:二分查找,nums[mid]>nums[upper]时取后半部分
nums[mid]<nums[lower]时取前半部分
nums[lower]==nums[mid]&&nums[mid]==nums[upper] 三者相等时upper--;
(nums[lower]<nums[mid]&&nums[mid]<nums[upper])||(nums[lower]<nums[mid]&&nums[mid]==nums[upper])||(nums[lower]==nums[mid]&&nums[mid]<nums[upper])所有其他可能性,此时有序直接返回最小的
int minl(int a,int b) { if(a>b) return b; return a; } class Solution { public: int findMin(vector<int>& nums) { int lower=0,upper=nums.size()-1,mid=lower+(upper-lower)/2; while(lower<mid) { if(nums[mid]>nums[upper]) { lower=mid; mid=lower+(upper-lower)/2; continue; } if(nums[mid]<nums[lower]) { upper=mid; mid=lower+(upper-lower)/2; continue; } if((nums[lower]<nums[mid]&&nums[mid]<nums[upper])||(nums[lower]<nums[mid]&&nums[mid]==nums[upper])||(nums[lower]==nums[mid]&&nums[mid]<nums[upper])) { return nums[lower]; } if(nums[lower]==nums[mid]&&nums[mid]==nums[upper]) { upper--; mid=lower+(upper-lower)/2; continue; } } return minl(nums[lower],nums[upper]); } };
leetcode 33. 搜索旋转排序数组
class Solution { public: int sets=-1; void ser_seg(vector<int>& nums, int target,int start,int end) { int mid=(start+end)/2; if(nums[mid]==target)//返回条件 { sets=mid; return; } if(nums[start]==target) { sets=start; return; } if(nums[end]==target) { sets=end; return; } if(start+1==end) return; if(nums[start]<nums[mid])//前面正序 { if(nums[start]<target&&target<nums[mid]) ser_seg(nums,target,start,mid); else ser_seg(nums,target,mid,end);//否则在后面 } else if(nums[mid]<nums[end])//后面正序 { if(nums[mid]<target&&target<nums[end]) ser_seg(nums,target,mid,end); else ser_seg(nums,target,start,mid); } return; } int search(vector<int>& nums, int target) { if(nums.size()==0) return -1; if(nums.size()==1) { if(nums[0]==target) return 0; return -1; } ser_seg(nums,target,0,nums.size()-1); return sets; } };
leetcode 34. 在排序数组中查找元素的第一个和最后一个位置
class Solution { public: int start=99999999; int end=-1; int max(int x,int y) { return (x>y?x:y); } void seg_s(vector<int>& nums,int x,int y,int target) { int mid=(x+y)/2; if(x==y) { if(nums[mid]==target) { start=min(mid,start); end=max(mid,end); } return; } if(x+1==y) { if(nums[x]==nums[y]) { if(nums[mid]==target) { start=min(x,start); end=max(y,end); } return; } else if(nums[x]==target) { start=min(x,start); end=max(x,end); return; } else if(nums[y]==target) { start=min(y,start); end=max(y,end); return; } else { int start=99999999; int end=-1; return; } } if(nums[mid]<target) { seg_s(nums,mid,y,target); } else if(nums[mid]>target) { seg_s(nums,x,mid,target); } else if(nums[mid]==target) { start=min(start,mid); end=max(mid,end); seg_s(nums,x,mid,target); seg_s(nums,mid,y,target); } return; } vector<int> searchRange(vector<int>& nums, int target) { vector<int> result(2,-1); if(nums.size()==0) return result; if(nums.size()==1) if(nums[0]!=target) return result; seg_s(nums,0,nums.size()-1,target); if(start==99999999) start=-1; result[0]=start;result[1]=end; return result; } };