关于二分排序的一些理解

首先我的思考源于一道leetcode题目

给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。
示例 1:
输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]
示例 2:
输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]
示例 3:
输入:nums = [], target = 0
输出:[-1,-1]
提示:
0 <= nums.length <= 105
-109 <= nums[i] <= 109
nums 是一个非递减数组
-109 <= target <= 109

解答代码请品鉴:

   public static void main(String[] args) {
        int []nums = new int[]{1,2,3,5,5,8,8,8,10,13,15};
        int target = 8;
        int[] result = new BiSerch().searchRange(nums, target);
        for (int i = 0; i < result.length; i++) {
            System.out.println(result[i]);
        }
    }

//从这里开始----------------------------------------------------------
    public int[] searchRange(int[] nums, int target) {
        int leftIdx = binarySearch(nums, target, true);
        int rightIdx = binarySearch(nums, target, false) - 1;
        if (leftIdx <= rightIdx && rightIdx < nums.length && nums[leftIdx] == target && nums[rightIdx] == target) {
            return new int[]{leftIdx, rightIdx};
        }
        return new int[]{-1, -1};
    }

    public int binarySearch(int[] nums, int target, boolean lower) {//这里主要是将lower(leftIdx)与upper(rightIdx)的解法合并了,且看下面:
        int left = 0, right = nums.length - 1, ans = nums.length;
        while (left <= right) {//这里代表的是 左闭右闭([left,right]这里是数学的[]不是说数组)
            int mid = (left + right) / 2;
            if (nums[mid] > target || (lower && nums[mid] >= target)) {//其实这里的ums[mid] >= target可改为 ==的,它本质就是在补当 == 的空
            //这里当lower == true时是相当与nums[mid] >= target;
            //当lower == false时是相当于nums[mid] > target;
                right = mid - 1;
                ans = mid;
            } else {
                left = mid + 1;
            }
        }
        return ans;
    }

那么我所思考的是什么问题呢?那就是它的这个nums[mid] > target 与 nums[mid] >= target 对这个二分搜索的影响是什么?有什么区别?
如果我们不解决这个问题,那么我们不得不靠在脑海一直模拟来思考整个运作过程,显然这不利于我们去快速的思考以及抽象(一般化)它的过程?
问题一(影响是什么?):他影响的是left 与 right 这两个指针谁来移动。
问题二(有什么区别?):在这一题中,我们结合问题一可知,这个等于号落在谁的身上(left or right),那么这个指针就会在nums[mid] == target的时候向另一个指针收缩(靠近),直到left = right - 1时结束,因为这个时候,mid会落在left身上(left + ( (left+1)- left )/ 2) = left),当在nums[mid] >= target 条件下,在nums[mid] = target时,由right指针向left指针移动,当leit = mid 所指数组不等于target时left右移,mid又变成

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

“胡”说八道

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值