有关二分法的一些整理与学习

常见二分法及其变形整理

二分法适用于有序数组,可以将时间复杂度由O(m)降低为O(logm)
(1)数组有序且不重复,确定value在数组A中的位置

思路:利用双指针动态查找value在数组A中的位置,迭代停止的条件是当low > high的时候,表明已经遍历完全

    //当数组 有序 且 不重复的时候,确定 value 在 数组 A 中的位置
    public static int binarySearch(int[] A, int value) {
        //数组长度 以及两个指针
        int length = A.length;
        int low = 0;
        int high = length - 1;
        //迭代停止的条件是 low > high
        while (low <= high) {
            //设置中值
            int mid = low + ((high - low) >> 1);
            //判断一下 value 的位置
            if (value < A[mid]) {
                high = mid - 1;
            } else if (value > A[mid]) {
                low = mid + 1;
            } else
                return mid;
        }
        return -1;
    }

(2)数组有序且重复,查找数组A中第一个等于value的位置

    //数组有序且存在重复 查找在数组A中第一个等于value的位置 第一种方法
    public static int binarySearchFirstOne(int[] A, int value) {
        int length = A.length;
        int low = 0;
        int high = length - 1;
        while (low <= high) {
            int mid = low + ((high - low) >> 1);
            if (value < A[mid])
                high = mid - 1;
            else if (value > A[mid])
                low = mid + 1;
            else {
                //相等的话 判断一下当前的位置
                // 如果当前位置已经到达 索引 0 那么不需要再判断 直接返回 mid 即可
                //如果当前位置不是 索引 0 那么它一定比 1 大,故 mid >= 1
                // 此时判断一下A[mid-1]的值,一定不会越界(比如说A[-1])
                //满足if 条件直接返回,
                // 如果不满足,说明在 low 和 mid 中间一定还有 value
                //更改high 为 mid-1即可
                if (mid == 0 || A[mid - 1] != value)
                    return mid;
                else
                    high = mid - 1;
            }
        }
        return -1;
    }

** (3)数组有序且存在重复,查找数组A中最后一个等于value的位置**

 //数组有序 且存在重复 查找最后一个 等于 value的数组 的方法一
    public static int binarySearchLastOne(int[] A, int value) {
        int length = A.length;
        int low = 0;
        int high = length - 1;
        while (low <= high) {
            int mid = low + ((high - low) >> 1);
            if (value < A[mid])
                high = mid - 1;
            else if (value > A[mid])
                low = mid + 1;
            else {
                if (mid == length - 1 || A[mid + 1] != value)
                    return mid;
                else
                    low = mid + 1;
            }
        }
        return -1;
    }

(4)数组有序且存在重复,在数组A中查找第一个大于等于value的值的位置

    //数组有序 且存在重复 查找第一个大于等于给定元素value的位置
    public static int binarySearchFirstGreatOrEqual(int[] A, int value) {
        int length = A.length;
        int low = 0;
        int high = length - 1;
        while (low <= high) {
            int mid = low + ((high - low) >> 1);
            if (value > A[mid])
                low = mid + 1;
            else {
                if (mid == 0 || A[mid - 1] < value)
                    return mid;
                else
                    high = mid - 1;
            }
        }
        return -1;
    }

(5)数组有序且存在重复,在数组A中查找最后一个小于等于value的位置

    //数组有序 且存在重复 查找最后一个小于等于给定值 value 的 位置
    public static int binarySearchLastLessOrEqual(int[] A, int value) {
        int length = A.length;
        int low = 0;
        int high = length - 1;
        while (low <= high) {
            int mid = low + ((high - low) >> 1);
            if (value < A[mid])
                high = mid - 1;
            else {
                if (mid == length - 1 || A[mid + 1] > value)
                    return mid;
                else
                    low = mid + 1;
            }
        }
        return -1;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值