704.二分查找

题目

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


示例 1:

输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4
示例 2:

输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1
 

提示:

你可以假设 nums 中的所有元素是不重复的。
n 将在 [1, 10000]之间。
nums 的每个元素都将在 [-9999, 9999]之间。

这道题写了两次

img

分析下第一次的代码:

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int l = 0, r = nums.size() - 1;
        while (l < r)
        {
            int mid = (l + r) >> 1;
            if (nums[mid] < target)
                l = mid + 1;
            else r = mid;
        }
        if (nums[l] == target)
            return l;
        return -1;
    }
};

第一次的执行时间不太理想,通过看别人的题解发现可以把if条件再细化点,如果找到了就直接退出函数,而不是等while条件不满足了才退出。

于是改进得到第二次写法:

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int l = 0, r = nums.size() - 1;

        while (l < r)
        {
            int mid = (l + r) >> 1;
            if (target > nums[mid]) l = mid + 1;
            else if (target == nums[mid]) return mid;
            else r = mid - 1;
        }

        if (nums[l] != target) return -1;
        return l;
    }
};

但是第二次写法其实还有改进空间,附上官方题解就知道为什么了:

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0, right = nums.size() - 1;
        while(left <= right){
            int mid = (right - left) / 2 + left;
            int num = nums[mid];
            if (num == target) {
                return mid;
            } else if (num > target) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return -1;
    }
};

主要是对return的处理上,其实如果不是在while循环里return,那么肯定没找到,所以在while循环外返回-1就行了。

还有就是在求mid上,官方写法避免了若left和right相加过大导致溢出的问题。

附上y总二分模板:二分查找算法模板

在看卡哥代码随想录视频的二分法那一个视频的时候,有了点新的感悟,感觉对思考这道题的不同写法有帮助。

感悟:边界的处理规则和区间定义有很大关系(区间定义一般是是左闭右开,左闭右闭),我们在写边界处理规则的时候一定要保证边界是合法的,然后结合一些东西根据区间定义去合理的做某些操作。

附上卡哥二分查找链接:二分查找

posted @ 2024-10-19 23:18  hisun9  阅读(4)  评论(0编辑  收藏  举报