二分查找及其拓展

二分查找及其拓展

1、最基础的二分查找

给定一个有序数组arr[],判断这个有序数组里面是否包含num数字

 public static boolean find(int[] arr, int num) {
        if (arr == null || arr.length == 0) {
            return false;
        }
        int L = 0;
        int R = arr.length - 1;
        int mid = L;
    
        while (L <= R) {
            mid = (R + L) / 2;
            if (arr[mid] > num) {
                R = mid - 1;
            } else if (arr[mid] < num) {
                L = mid + 1;
            } else {
                return true;
            }
        }
        return false;
    }

2、给定一个有序数组arr,查找大于等于num的最左侧的位置下标

  /**
         * arr有序 >=num 最左
         *
         * @param arr 有序数组
         * @param num 查找的数
         * @return 最左的>=num位置
         */
    public static int mostLeftNoMorNumIndex(int[] arr, int num) {
        if (arr == null || arr.length == 0) {
            return -1;
        }
    
        int L = 0;
        int R = arr.length - 1;
        int ans = -1; 
        while (L <= R) {
            int mid = (L + R) / 2;
            if (arr[mid] >= num) {
                ans = mid;
                R = mid - 1;
            } else {
                L = mid + 1;
            }
        }
        return ans;
    }

3、给定一个有序数组arr,找到小于等于num最右的位置

   public static int lessRightNoMorNumIndex(int[] arr, int num) {
        if (arr == null || arr.length == 0) {
            return -1;
        }
    
        int L = 0;
        int R = arr.length - 1;
        int ans = -1;
        while (L <= R) {
            int mid = (L + R) / 2;
            if (arr[mid] <= num) {
                ans = mid;
                L = mid + 1;
            } else {
                R = mid - 1;
            }
        }
        return ans;
    }

4、局部最小值问题

arr数组是无序的,且arr任意两个相邻的数不相等,假设长度为0,局部最小的定义

arr[0] < arr[1] , 则0位置为局部最小
arr[N-2] > arr[N-1] , 则N-1位置为局部最小
arr[i-1] < arr[i] < arr[i+1],则i位置为局部最小

请你返回一个局部最小?

    /**
         * arr 整体无序,相邻的数不相等
         *
         * @param arr
         * @return
         */
    public static int oneMinIndex(int[] arr) {
        if (arr == null || arr.length == 0) {
            return -1;
        }
        int N = arr.length;
        if (N == 1) {
            return 0;
        }
        if (arr[0] < arr[1]) {
            return 0;
        }
        if (arr[N - 1] < arr[N - 2]) {
            return N - 1;
        }
        // arr.length> 2
        int L = 0;
        int R = N - 1;
        while (L < R - 1) {
            int mid = (R + L) / 2;
            if ((arr[mid] < arr[mid + 1]) && (arr[mid - 1] > arr[mid])) {
                // 左 < 我 < 右
                return mid;
            } else { // 不同时小
                if (arr[mid] > arr[mid - 1]) {
                    // 左 < 我
                    R = mid - 1;
                    continue;
                } else {
                    // 右 < 我
                    L = mid + 1;
                    continue;
                }
            }
        }
    
        return arr[L] < arr[R] ? L : R;
    }



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值