二分查找
基本排序算法,就不赘述了,直接上代码。
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length-1;
while(left <= right){
int mid = (left+right)/2;
if(nums[mid] == target){
return mid;
}
if(nums[mid] > target){
right = mid-1;
}else{
left = mid + 1;
}
}
return -1;
}
}
查找第一个大于k的数
也可以理解为 查找大于k的最小数, nums[i] > k ,有时也会是大于等于。
即k的后继。
直接上代码
public int findFirstMax(int[] nums, int k){
int left = 0;
int right = nums.length-1;
int mid;
while(left<right){
mid = (left+right) >> 1;
// 如果mid大于k
if(nums[mid] > k){
right = mid;
}else{
left = mid + 1;
}
}
return left; // left和right相等,返回谁都一样
}
如果可能无解,right = nums.length即可。
查找最后一个小于k的数
也可以理解为 查找小于k的最大值
即k的前驱
public int findFirstMin(int[] nums, int k){
// 最后一个小于K的数 小于k的最大值 <k k的前驱
int left = 0; //如果可能无解,left=-1
int right = nums.length-1;
int mid;
while(left<right){
mid = (left+right+1) << 1;
// 如果mid大于k
if(nums[mid] < k){
left = mid;
}else{
right = mid - 1;
}
}
return right;// left和right相等,返回谁都一样
}
如果可能无解,left=-1即可。
总结模版
首先判断是寻找k的前驱还是后继,有无可能无解。
然后直接三步走:
- 写出二分的条件不等式。如:寻找大于k的最小值 > k
- 把条件放入if中,如:if(mid>k)
并确定满足条件时要不要自己(mid)。如果要小的(right=mid) 还是要大的(left=mid)。 - 另一半放入else( left=mid+1 或者 right=mid-1) 如果是后者,求mid时补个+1
若题目有无解情况,上界+1 或者下界-1,用于表示无解。
二分查找防止溢出
int mid = left + ((right - left) >> 1);
该思维较多和动态规划配合使用,务必掌握