一、用途
在数组中查找某一特定值的函数并获取其下标。
二、限制条件
1. 有序数组:vector[],array[]
所查找的数组中的所有元素必须按照从小到大或从大到小的顺序排列。
如果所查找的数组不是有序数组,也可使用sort()库函数将其转化为升序排列的有序数组后再进行查找。其中sort()函数位于C++的algorithm库中,其具体用法如下:
#include <iostream>
#include <algorithm> // 包含sort()函数
using namespace std; // sort()函数位于标准库中
int arr[] = {0,2,1,3,7,4,3,2,5};
int n = sizeof(arr)/sizeof(arr[0]); // n为数组的长度
// 默认为升序排序
sort(arr, arr + n);
// 降序排列
sort(arr, arr + n, greater<int>());
2. 数组中无重复元素
若存在重复元素,函数将返回其中某一个元素的地址。
三、时空复杂度
- 时间复杂度:O(logn)
- 空间复杂度:O(1)
四、查找区间的两种模式
// target定义在左闭右闭区间
class Solution {
public:
int searchInsert_one(vector<int>& nums, int target) {
int len = nums.size();
int left = 0;
int right = len - 1;
while( left <= right) { // 当left = right 时,有查找成功的可能,故使用 <=
int middle = left + ((right - left)/2);
if(nums[middle] < target)
left = middle + 1; // 由于middle位置取不到,故移动至middle +1提升效率
else if(nums[middle] > target)
right = middle - 1; // 同理
else
return middle;
}
// 若target大于数组中的所有元素,则将其插入数组末尾
return right + 1;
}
};
// target定义在左闭右开区间
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;
// 由于右界为开,无法取到,所以将right 赋值为同样无法取到的 middle
} else if (nums[middle] < target) {
left = middle + 1; // target 在右区间,在[middle + 1, right)中
} else { // nums[middle] == target
return middle; // 数组中找到目标值,直接返回下标
}
}
// 未找到目标值
return -1;
}
};
五、其他注意事项
// int middle;
middle = left + ((right - left) >> 1); // 防止两数相加导致大数溢出