二分查找算法

搜索区间为闭区间

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

搜索区间为[0, nums.length-1], 对于给定的mid,区间分为[0,mid-1],mid,[mid+1,nums.length-1]三部分,因此若num[mid]=target则返回,否则搜索左区间,要不然搜索右区间。

搜索区间为开区间

搜索区间为[0, nums.length)。对于给定的mid,搜索区间被分为三份[0, mid),mid,[mid+1,num.length)。由于没有返回语句,下一次搜索的区间相对于上次来说必须要缩小,否则会出现死循环的情况。

  1. 搜索左侧
    搜索左侧时当nums[mid]==target时,要搜索[0,mid)区间,最终找到最左侧元素是要返回left因为此时的区间为[mid,mid)。
public static int binarySerachLeft(int[] nums, int target){
        int left = 0;
        int right = nums.length;
        while (left < right){
            int mid = (left + right)/2;
            if(target == nums[mid]){
                right = mid;//区间为[left, mid),搜索区间缩小了
            }else if(target > nums[mid]){
                left = mid + 1;//区间为[left, mid),搜索区间缩小了
            }else{
                right= mid;//区间为[mid + 1, right),搜索区间缩小了
            }
        }
        //需要判断left是否等于nums.length,因为搜索区间为[0, nums.length),
        // 当搜索区间为空时得到的区间可能为[nums.length, nums.length)
        //不用判断left是否小于0,因为搜索区间为空时得到[0, 0)
        return left >= nums.length || nums[left] != target?-1:left;
    }
  1. 搜索右侧
    搜索右侧时,当nums[mid] = target时要搜索[mid+1,nums.length)区间,最后返回结果时要返回left-1(因为满足条件就往右搜索,最后返回的left正好是第一个不满足条件的,left - 1是最后一个满足条件的)。
public static int binarySerachRight(int[] nums, int target){
        int left = 0;
        int right = nums.length;
        while (left < right){
            int mid = (left + right)/2;
            if(target == nums[mid]){
                left = mid + 1;	//搜索区间为[mid + 1, right) 变小了
            }else if(target > nums[mid]){
                left = mid+ 1;	//搜索区间为[mid + 1, right) 变小了
            }else{
                right = mid;	//搜索区间为[left, mid) 变小了
            }
        }
        //需要判断left是否等于nums.length,因为搜索区间为[0, nums.length),
        // 当搜索区间为空时得到的区间可能为[nums.length, nums.length)
        //不用判断left是否小于0,因为搜索区间为空时得到[0, 0)
        return left - 1 < 0 || nums[left-1] != target?-1:left-1;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值