几种不同情况的二分

文章介绍了二分查找的基本实现,用于在有序数组中寻找目标元素,返回其索引。同时,讨论了针对存在重复元素的有序数组,如何寻找小于或大于特定值的最大/最小索引,并提供了相应的代码示例。需要注意,返回的索引值可能需要进一步判断是否满足实际需求。
摘要由CSDN通过智能技术生成
1.通常情况下二分用于在一个有序的数组中寻找一个目标元素,这样的需求很明确,实现起来也比较简单:能找到目标元素则返回对应元素在数组中的下标,否则返回一个不存在的索引值。

代码如下:

static int binarySearch(int[] array, int target) {
        int left = 0;
        int right = array.length - 1;
        int mid;
        while (left <= right) {
            mid = (left + right) >> 1;
            if (array[mid] == target) {
                return mid;
            } else if (array[mid] < target) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return -1;
    }

(这里给出Arrays.java中的源码):

 private static int binarySearch0(int[] a, int fromIndex, int toIndex,
                                     int key) {
        int low = fromIndex;
        int high = toIndex - 1;

        while (low <= high) {
            int mid = (low + high) >>> 1;
            int midVal = a[mid];

            if (midVal < key)
                low = mid + 1;
            else if (midVal > key)
                high = mid - 1;
            else
                return mid; // key found
        }
        return -(low + 1);  // key not found.
    }
2.因为有序的集合里可能会存在多个元素相同的情况,所以可能会有以下两种需求:

求小于某个值的最大索引、求大于某个值的最小索引。比如:

给出一个有序的数组:[2,3,3,3,4,5]

小于4的最大索引是3,大于2的最小索引是1。

求小于某个值的最大索引代码如下:

 static int binarySearch(int[] array, int target) {
        int left = 0;
        int right = array.length;
        int mid;
        while (left + 1 < right) {
            mid = (left + right) >> 1;
            if (array[mid] >= target) {
                right = mid - 1;
            } else {
                left = mid;
            }
        }
        return left;
    }

求大于某个值的最小索引代码如下:

static int binarySearch(int[] array, int target) {
        int left = 0;
        int right = array.length - 1;
        int mid;
        while (left < right) {
            mid = (left + right) >> 1;
            if (array[mid] <= target) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        return left;
    }

这里给出说明,由于返回的索引值范围在0~array.length-1,因此可能会出现返回值是一个不符合要求的答案,需要自己判断。比如:

在求小于某个值的最大索引时:

对于数组[2,3,3,3,4,5],target=1时,返回值为0,很明显array[0]>1。

在求大于某个值的最小索引

对于数组[2,3,3,3,4,5],target=6时,返回值为5,很明显array[5]<6。

再有,如果条件变为小于等于某个值的最大索引或者大于等于某个值的最小索引时,只需要将判断条件中的>=变为><=变为<即可。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值