leetcode -二分查找

704 二分查找

leetcode

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

  public int search(int[] nums, int target) {
        if (nums == null || nums.length == 0) {
            return -1;
        }
        int l = 0;
        int r = nums.length - 1;
        while(l <= r) {
            int mid = (l + r) >> 1;//考虑溢出的问题,可以写成 l + (r - l) / 2
            if (nums[mid] == target) {
                return mid;
            }
            else if (nums[mid] > target) {
                r = mid - 1;
            }
            else {
                l = mid + 1;
            }
        }
        return - 1;
    }
  1. 第一个错误的版本

leetcode

有 n 个版本 [1, 2, ..., n],找出导致之后所有版本出错的第一个错误的版本。
可以通过调用 bool isBadVersion(version) 接口来判断版本号 version 是否在单元测试中出错。
尽量减少对调用 API 的次数。

  public int firstBadVersion(int n) {
        int l = 1;
        int r = n;
        while(l < r) {
            int mid = l + (r - l) / 2;
            if (isBadVersion(mid)){
                r = mid;
            }
            else {
                l = mid + 1;
            }
        }
        return l;
    }
  1. 搜索插入位置

leetcode

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。
如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

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

关于二分的思想,其实就是依据性质将数据一分为二,一半满足,一半不满足
主要是细节方面的,可以看一下下面的文章

二分查找

下面这两个模版是我看y神的笔记,就是关于二分是否要加1,r = mid的时候,就不需要加1,当 l = mid的时候就要加1,
如果一开始不怎么理解二分的细节问题,可以先照着模版写,多写几次,一边写,一边思考,或者在纸上面演示一遍。

public int bsearch_1(int l, int r)
{
    while (l < r)
    {
        int mid = l + r >> 1;
        if (check(mid)) r = mid;    // check()判断mid是否满足性质
        else l = mid + 1;
    }
    return l;
}

// 区间[l, r]被划分成[l, mid - 1]和[mid, r]时使用:

public int bsearch_2(int l, int r)
{
    while (l < r)
    {
        int mid = l + r + 1 >> 1;
        if (check(mid)) l = mid;
        else r = mid - 1;
    }
    return l;
}
posted @ 2021-07-02 23:02  梨云梦暖  阅读(25)  评论(0)    收藏  举报