二分查找的两种方法

对应的力扣题目
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
我在此通过对区间的选择描述了两种方法。

直接上代码
一:

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size() - 1; // 定义target在左闭右闭的区间里,[left, right]
        while (left <= right) { // 当left==right,区间[left, right]依然有效,所以用 <=
            int middle = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2
            if (nums[middle] > target) {
                right = middle - 1; // target 在左区间,所以[left, middle - 1]
            } else if (nums[middle] < target) {
                left = middle + 1; // target 在右区间,所以[middle + 1, right]
            } else { // nums[middle] == target
                return middle; // 数组中找到目标值,直接返回下标
            }
        }
        // 未找到目标值
        return -1;
    }
};

①:左闭右闭
此时选择左闭右闭,假如没有目标值最后的结果是 left = right,存在目标值的表现是left > right。显而易见,当中间值大于标准值,则排除了中间值,right应等于middle-1。
二:

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

②:左闭右开
此时选择左闭右开,因为左闭右开的情况右边不可取值,所以不存在 left = right。当选取左区间时,因为是左闭右开取不到右边的值,right应为非标准值,即right = middle,取右区间,左值可能为标准值,则left = middle +1。

上一篇:关于二分法的边界问题及两种写法


下一篇:leetcode1219 黄金旷工 middle