# 题目
给定一个 n
个元素有序的(升序)整型数组 nums
和一个目标值 target
,写一个函数搜索 nums
中的 target
,如果目标值存在返回下标,否则返回 -1
。
提示:
- 你可以假设
nums
中的所有元素是不重复的。 n
将在[1, 10000]
之间。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; | |
} | |
}; |