Given an array of integers nums
which is sorted in ascending order, and an integer target
, write a function to search target
in nums
. If target
exists, then return its index. Otherwise, return -1
.
You must write an algorithm with O(log n)
runtime complexity.
Example 1:
Input: nums = [-1,0,3,5,9,12], target = 9 Output: 4 Explanation: 9 exists in nums and its index is 4
Example 2:
Input: nums = [-1,0,3,5,9,12], target = 2 Output: -1 Explanation: 2 does not exist in nums so return -1
Constraints:
1 <= nums.length <= 104
-104 < nums[i], target < 104
- All the integers in
nums
are unique. nums
is sorted in ascending order.
1.左闭右开写法:
注意事项:区间内定义是否合法,主要表现为以下三个地方:
(1)int right=nums.size();
因为右边的是开,所以right的值应该比最大的下标+1
(2)while(left<right)
当left=right的时候,区间是不合法的,所以left!=right
(3)if(nums[middle]>target){
right=middle;
}
在这里,right=middle, 因为右边的是开,right的值是取不到的,所以可以等于middle。
还有一点就是后面else if的判断句,left=middle+1,如果写成left=middle的话,会超出时间限制。
class Solution {
public:
int search(vector<int>& nums, int target) {
int left=0;
int right=nums.size();
while(left<right){
int middle=(left+right)/2;
if(nums[middle]>target){
right=middle;
}
else if(nums[middle]<target){
left=middle+1;
}
else{
return middle;
}
}
return -1;
}
};
2.左闭右闭写法:
注意事项:依旧是区间的合法性,具体体现为以下四点:
(1)int right=nums.size()-1;
因为右边的是闭,所以right的值应该=最大的下标
(2)while(left<=right)
当left=right的时候,区间是合法的,所以left可以=right,不要漏了这个条件
(3)if(nums[middle]>target){
right=middle-1;
}
在这里,right=middle-1, 因为右边的是闭,right的值是取得到的,在if条件判断中已经判断了middle下标的值>target,如果不是middle-1的话,在边界条件上就会出问题了,因为右边是闭。
(4)else if(nums[middle]<target){
left=middle+1;
}
left=middle+1,理由同(3)
class Solution {
public:
int search(vector<int>& nums, int target) {
int left=0;
int right=nums.size()-1;
while(left<=right){
int middle=(left+right)/2;
if(nums[middle]>target){
right=middle-1;
}
else if(nums[middle]<target){
left=middle+1;
}
else{
return middle;
}
}
return -1;
}
};
总之,两种写法都可以,最重要的是看区间的边界是否合法。