有序无重复
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
- 有序
- 元素无重复
左闭右闭即[left, right]
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size()-1;
while(left<=right){ // 闭区间,故取等号有意义
int mid = left + (right-left)/2; //防止溢出
if(nums[mid]>target){
right = mid -1; // 减1 因为nums[mid]一定不是target
}else if(nums[mid]<target){
left = mid+1; // 同理加1 因为nums[mid]一定不是target
}else{
return mid;
}
}
// return left; 表示二分查找元素插入的位置
return -1;
}
};
- 时间复杂度:O(log n)
- 空间复杂度:O(1)
左闭右开即[left, right)
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size();
while(left<right){ // [left, right) left===right无意义
int mid = left + (right-left)>>1; //防止溢出
if(nums[mid]>target){
right = mid; // target 在左区间,在[left, middle)中
}else if(nums[mid]<target){
left = mid+1; // target 在右区间,在[middle + 1, right)中
}else{
return mid;
}
}
// return right; 表示二分查找元素插入的位置
return -1;
}
};
- 时间复杂度:O(log n)
- 空间复杂度:O(1)
有序重复
给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
- 有序
- 有重复元素
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int leftBorder = getLeftBorder(nums,target);
int rightBorder = getRightBorder(nums,target);
// 1.没找到
if(leftBorder==-2 || rightBorder ==-2) return {-1,-1};
// 2.找到
if(rightBorder-leftBorder>1) return {leftBorder+1,rightBorder-1};
return {-1,-1};
}
private:
int getRightBorder(vector<int>& nums, int target){
int left = 0;
int right = nums.size()-1;
int rightBorder = -2;
while(left<=right){
int mid = left + (right-left)/2;
if(target>=nums[mid]){ //寻找右边界,当target=nums[mid]时,更新右边界
left = mid+1;
rightBorder=left;
}else{
right = mid-1;
}
}
return rightBorder;
}
int getLeftBorder(vector<int>& nums, int target){
int left = 0;
int right = nums.size()-1;
int leftBorder = -2;
while(left<=right){
int mid = left + (right-left)/2;
if(target<=nums[mid]){ //寻找左边界,当target=nums[mid]时,更新左边界
right = mid-1;
leftBorder=right;
}else{
left = mid+1;
}
}
return leftBorder;
}
};