算法与数据结构(二)--二分法

算法与数据结构(二)--二分法

二分法定义

二分法(Bisection method) 即一分为二的方法. 设[a,b]为R的闭区间. 逐次二分法就是造出如下的区间序列([an,bn]):a0=a,b0=b,且对任一自然数n,[an+1,bn+1]或者等于[an,cn],或者等于[cn,bn],其中cn表示[an,bn]的中点。(百度百科)

练习

1.找出有序数组里是否包含某个数字

	public static boolean NumIsExist(int[] sortedArr,int num) {
        if (null == sortedArr || sortedArr.length < 1) {
            return false;
        }
        int left = 0;
        int mid = 0;
        int right = sortedArr.length - 1;
        while(left < right) {
//          避免int数值越界
            mid = left + ((right - left) >> 1);
            if (num == sortedArr[mid]) {
                return true;
            } else if (num > sortedArr[mid]) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return num == sortedArr[left];
    }

2.找出有序数组中大于等于某个数的最左侧的位置

	public static int leftIndex(int[] sortedArr,int num) {
        int left = 0;
        int right = sortedArr.length - 1;
        int mid = 0;
        int index = -1;
        while (left <= right) {
            mid = left + ((right - left) >> 1);
            if (sortedArr[mid] >= num) {
                index = mid;
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return index;
    }
  1. 找出有序数组中小于等于某个数的最右侧的位置
	public static int rightIndex(int[] sortedArr,int num) {
       int left = 0;
       int right = sortedArr.length - 1;
       int mid = 0;
       int index = -1;
       while (left <= right) {
           mid = left + ((right - left) >> 1);
           if (sortedArr[mid] <= num) {
               index = mid;
               left = mid + 1;
           } else {
               right = mid - 1;
           }
       }
       return index;
    }

4.找出数组中的一个局部最小值
使用二分法查找并不是必须要求数组有序,只要能判断所查找数据能落在哪个区域内即可使用二分法。

public static int getLessIndex(int[] arr) {
        if (null == arr || arr.length == 0) {
            return -1;
        }
        if (arr.length == 1 || arr[0] < arr[1]) {
            return 0;
        }
        if (arr[arr.length - 1] < arr[arr.length - 2]) {
            return arr.length - 1;
        }
        int left = 1;
        int right = arr.length - 2;
        int mid = 1;
        while (left < right) {
            mid = left + ((right - left) >> 1);
//            选取段落的时候需要保证所选取段落端头的单调性,因此采用如下判断
			 //保证了所选段落右侧端头递增
            if (arr[mid] > arr[mid - 1]) {
                right = mid - 1;
            //保证了所选段落左侧端头递减
            } else if (arr[mid] > arr[mid + 1]) {
                left = mid + 1;
            } else {
                return mid;
            }
        }
        return left;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值