【二分查找】算法二分查找入门

153 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 2 天,点击查看活动详情

二分查找的定义

二分查找是计算机科学中最基本、最有用的算法之一。 它描述了在有序集合中搜索特定值的过程。 二分,顾名思义,我们需要将一个序列分成两半,再根据中间值和目标值的比较来确定目标值一定在其中的某一半序列内。然后我们保存这半个序列并将其也分成两半,重复以上操作,直到找到目标值为止。

例题

先上一道力扣上的题: 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。 原题连接

如果不用二分查找的话,那么我们碰到这道题应该是直接遍历一遍来查询target的下标,若查不到则直接返回-1。这种做法当然是可以的,就是效率可能会低点,如果数据量不大的话用这种方法是很合适的,但数据量上来的话还是二分查找的方法比较好,这也是我们要学习二分查找的目的之一。 下面的解法就是使用的二分查找:

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

上面的代码中用到了几个二分查找中的专业术语:

  • target:需要查找的目标值。
  • left,right:查找过程中的左边界和右边界。
  • mid:左右边界的中间值,用来与target比较来判断是保存右半部分还是左半部分。

解题思路

首先细读题目,能注意到题目中的几个条件: 有序,查找目标值。 一般有这两个条件基本上就能确定这题可以使用二分查找来解了。 首先确定左右边界,left和right。 一般left设为0,right设为数组长度-1。 随后一个while循环判断条件设为left<=right,当left大于right的时候循环便会停止。 在循环内定义mid,写成mid=((right-left)>>1)+left而不直接写成mid=(left+right)/2是为了防止左右边界的数值过大超出int的范围。 随后将nums[mid]与target进行比较。 若是相等就直接返回mid即可。 若是nums[mid]大于target则代表target在左半部分,这时候就需要收缩右边界到mid-1,不收缩到mid是为了防止当左右边界相等时陷入死循环。 同理,当nums[mid]小于target的时候,便意味着target在右边界,所以将left更新为mid+1; 最后,若是循环结束依然未找到值,则代表数组中没有target,便直接返回-1。