# 题目

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

提示:

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

力扣 704 二分查找

# 解法

# 分析

看到有序,无重复元素,可以考虑二分法。

二分查找的难点在于处理边界,可以左闭右闭或者左闭右开

左闭右闭

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;
    }
};

左闭右开

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size(); // 定义 target 在左闭右开的区间里,即:[left, right)
        while (left < right) { // 因为 left == right 的时候,在 [left, right) 是无效的空间,所以使用 <
            int middle = left + ((right - left) >> 1);
            if (nums[middle] > target) {
                right = middle; //target 在左区间,在 [left, middle) 中
            } else if (nums[middle] < target) {
                left = middle + 1; //target 在右区间,在 [middle + 1, right) 中
            } else { // nums[middle] == target
                return middle; // 数组中找到目标值,直接返回下标
            }
        }
        // 未找到目标值
        return -1;
    }
};
更新于