给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
要找到target的下标,使用二分查找需要定义左边界和右边界,分别是left和right
其中边界有两种写法,[左闭右闭] 和 [左闭右开] > [ left , right ] , [ left , right)
1.左闭右闭
此时 target 在 [ left , right ] 之间,外层判断是while(left <= right),此时的left == right是有意义的
即
class Solution {
public int search(int[] nums, int target) {
//左闭右开区间
int left = 0;
int right = nums.length - 1;
while(left <= right){
//处理过程
}
}
}
之后是判断middle位置的数和target的大小
若 nums[middle] < target,说明在右区间,则left = middle + 1
若nums[middle] > target,说明在左区间,则 right = middle - 1
最后返回时,如果数据存在,是定位在middle上,否则返回-1
完整代码:
class Solution {
public int search(int[] nums, int target) {
//左闭右开区间
int left = 0;
int right = nums.length - 1;
while(left <= right){
//处理过程
int middle = left + ((right - left)/2);//防止溢出
if(nums[middle] > target){
//在左区间
right = middle - 1;
}else if(nums[middle] < target){
left = middle + 1;
}else{
return middle;
}
}
return -1;
}
}
2.左闭右开
左闭右开是 [ left , right ) ,相当于right无意义。 这外层循环为while( left < right),因为left==right是无意义的。
注意此时right的长度为nums.length,无需-1,因为是右开区间。
class Solution {
public int search(int[] nums, int target) {
//左闭右开
int left = 0;
int right = nums.length;
while(left < right){
//处理数据
}
}
}
在判断nums[middle] 和 target 时
若nums[middle] > target,则right=middle,右闭为middle - 1 ,道理相同,都是不包括middle
若nums[middle] < target,则left=middle+1,和第一种写法相同。
完整代码
class Solution {
public int search(int[] nums, int target) {
//左闭右开
int left = 0;
int right = nums.length;
while(left < right){
//处理数据
int middle = left + ((right - left) / 2);
if(nums[middle] > target){
right = middle;
}else if(nums[middle] < target){
left = middle + 1;
}else{
return middle;
}
}
return -1;
}
}
//end