《算法通关村——基于二分查找的拓展问题》

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;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值