算法练习——二分查找
框架
int binarySearch(int[] nums,int target){
int left = 0,right=...;
while(...){
//防止left+right溢出
int mid=left+(right-left)>>1;
if(nums[mid]==target){
...
}else if(nums[mid]<target){
left = ...
}else if(nums[mid]>target){
right = ...
}
}
return ...;
}
寻找一个数
int binarySearch(int[]nums,int target){
int left = 0;
int right = nums.length-1;
while(left<=right){
int mid = left + (right-left)/2;
if(nums[mid]==target){
return mid;
}else if(nums[mid]>target){
right = mid-1;
}else if(nums[mid]<target){
left = mid+1;
}
}
return -1;
}
寻找左侧边界
int left_bound(int[]nums,int target){
if(nums.length==0) return -1;
int left=0,right=nums.length;
while(left<right){
int mid = left + (right-left)/2;
if(nums[mid]==target){
right = mid;
}else if(nums[mid]>target){
right = mid;
}else if(nums[mid]<target){
left = mid + 1;
}
}
if(left!=nums[target]){
return -1;
}
return left;
}
寻找右侧边界
int right_bound(int[]nums,int target){
if(nums.length==0) return -1;
int left=0,right=nums.length;
while(left<right){
int mid = left + (right-left)/2;
if(nums[mid]==target){
left = mid+1;
}else if(nums[mid]>target){
right = mid;
}else if(nums[mid]<target){
left = mid+1;
}
}
if(left!=nums[target]){
return -1;
}
return left-1;//!!!!!
}
二分的应用
875. 爱吃香蕉的珂珂
//二分找左边界
static int minEatingSpeed(int[] piles, int h) {
//二分搜索
int left = 1, right = maxInPile(piles) + 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (canEat(piles, mid, h)) {
right = mid;
} else {
left = mid+1;
}
}
return left;
}
static int maxInPile(int[] piles) {
int max = Integer.MIN_VALUE;
for (int i : piles) {
if (i > max) {
max = i;
}
}
return max;
}
static boolean canEat(int[] piles, int speed, int h) {
int cnt = 0;
for (int i : piles) {
cnt += (i / speed);
cnt += (i % speed) > 0 ? 1 : 0;
}
return cnt <= h;
}