难度:easy
简单的二分查找,需要注意的是每次判断和查找的边界处理:左闭右闭和左闭右开的查找在细节上的处理是不一样的;
二分查找前提是排序好的数组和无重复元素,如果有重复元素那要返回一个存储多个下标的数组;
Java:
左闭右闭:
class Solution {
public int search(int[] nums, int target) {
if (target < nums[0] || target >nums[nums.length - 1]) {
return -1;
}
//搜索区间[left, right],左闭右闭区间
int left = 0;
int right = nums.length - 1;
while (left <= right) {
int middle = (left + right) / 2;
if (nums[middle] < target) {
left = middle + 1;
}
else if (nums[middle] > target) {
right = middle - 1;
}
else if (nums[middle] == target) {
return middle;
}
}
return -1;
}
}
左闭右开:
class Solution {
public int search(int[] nums, int target) {
if (target < nums[0] || target >nums[nums.length - 1]) {
return -1;
}
//搜索区间[left, right),左闭右开区间
int left = 0;
int right = nums.length;
while (left < right) {
int middle = (left + right) / 2;
if (nums[middle] < target) {
left = middle + 1;
}
else if (nums[middle] > target) {
right = middle;
}
else if (nums[middle] == target) {
return middle;
}
}
return -1;
}
}
复杂度分析:
- 时间复杂度:O(logn),因为每次查找都把范围缩小了一半
- 空间复杂度:O(1)
在求mid时,我们可以优化:
int middle = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2