1.山脉数组的峰顶值
符合下列属性的数组arr称为山脉数组:
arr.length>=3,且存在i(0<i<arr.length-1)使得:
- arr[0]<arr[1]<.....<arr[i-1]<arr[i]
- arr[i]>arr[i+1]>.....>arr[arr,length-1]
题目要求:有一个山脉数组arr求出顶峰的索引,即arr[i]>arr[i-1]并且arr[i]<arr[i+1],求arr[i].
利用二分查找思路:
对于二分的某一个位置mid,mid可能有的如下3中情况:
- mid在上升阶段的时候,arr[mid]>arr[mid-1]&&arr[mid]<a[mid+1]
- mid在顶峰的时候,arr[mid]>arr[mid-1]&&arr[mid]<arr[mid+1]
- mid在下降的时候,arr[mid]>arr[mid+1]&&arr[mid]<arr[mid-1]
因此我们可以根据mid的位置调整左右指针,具体代码如下:
public class Test01 {
//测试
public static void main(String[] args) {
System.out.println("封顶值为:"+test(new int[{1,3,4,7,8,9,12,15,13,12,11,10,8,5,2}));
}
//方法
public static int test(int[] arr) {
int left = 1;
int right = arr.length - 2;
while(left<right) {
int mid = left+((right-left)>>1);
if(arr[mid]>arr[mid-1]&&arr[mid]>arr[mid+1]) {
return mid;
}else if(arr[mid]>arr[mid-1]&&arr[mid]<arr[mid+1]) {
left = mid + 1;
}else if(arr[mid]>arr[mid+1]&&arr[mid]<arr[mid-1]){
right = mid - 1;
}
}
return left;
}
}
2.找缺失的数字
题目要求:一个长度为n-1的递增排序数组arr中的所有数字都是唯一的,婢妾每一个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中只有一个数字不在该数组中,使用二分查找找出这个数字。
思路:只需找到第一个arr[mid] != mid,此时mid即为缺失的数字,具体代码如下:
public class Test2 {
//测试
public static void main(String[] args) {
System.out.println("缺失的数字为:"+test(new int[]{0,1,2,4,5,6,7,8,9}));
}
//方法
public static int test(int[] arr) {
int left = 0;
int right = arr.length - 1;
while(left<=right) {
int mid = left+((right-left)>>1);
if(arr[mid] == mid) {
left = mid + 1;
}else {
right = mid - 1;
}
}
return left;
}
}
3.优化求平方根
题目要求:利用二分查找实现sqrt(int x)方法,求x的平方根。
public class Test3 {
//测试
public static void main(String[] args) {
System.out.println("缺失的数字为:"+test(256));
}
//方法
public static int test(int x) {
int left = 1;
int right = x;
while(left <= right) {
int mid = (left+right)/2;
if(mid == x/mid) {
return mid;
}else if(mid > x/mid) {
right = mid - 1;
}else if(mid < x/mid) {
left = mid + 1;
}
}
return left;
}
}