题目
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值,返回 [-1, -1]。
输入: nums = [5,7,7,8,8,10], target = 8
输出: [3,4]
输入: nums = [5,7,7,8,8,10], target = 6
输出: [-1,-1]
思路
- 寻找一个值
int left = 0;
int right = nums.length-1;
while(left<=right){
int mid = left + (right - left) / 2;
if(nums[mid] == target)
return mid;
else if (nums[mid] < target)
left = mid + 1; // 注意
else if (nums[mid] > target)
right = mid-1 ; // 注意
}
return -1;
- 寻找左侧边界
【寻找右边界时 收缩左的时候条件加等于】
寻找左侧边界,mid等于时收缩右侧边界,最后返回left
left = 0;right = nums.length-1;
while(left<=right){
int mid = left+(right-left)/2;
if(nums[mid]<target) left = mid+1;
else right = mid-1;
}
int left = 0;
int right = nums.length-1;
while(left<=right){
int mid = left + (right - left) / 2;
if(nums[mid] == target)
right = mid-1;//!!!收缩右侧边界
else if (nums[mid] < target)
left = mid + 1; // 注意
else if (nums[mid] > target)
right = mid-1 ; // 注意
}
//检查出界情况
if(left>=nums.length||nums[left]!=target){
return -1;
return left;
- 寻找右侧边界
寻找右侧边界,mid等于时收缩左侧边界,最后返回right
int left = 0;
int right = nums.length-1;
while(left<=right){
int mid = left+(right-left)/2;
if(nums[mid]<=target) left = mid+1;
else right = mid-1;
}
————————————————
版权声明:本文为CSDN博主「Betternw」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_42215827/article/details/106877330
int left = 0;
int right = nums.length-1;
while(left<=right){
int mid = left + (right - left) / 2;
if(nums[mid] == target)
left = mid+1;//!!!收缩左侧边界
else if (nums[mid] < target)
left = mid + 1; // 注意
else if (nums[mid] > target)
right = mid-1 ; // 注意
}
if(right<0||nums[right]!=target){
return -1;
return right;
本题:
因为是要寻找相同元素的起始位置。先用二分法定位到给定的一个元素,然后对这个元素是第一个还是最后一个进行调整。
引入一个布尔值,进行第一个和最后一个元素的区分。
当寻找第一个时的边界条件是前一个和当前不相等。否则缩小右边界继续移动。
当寻找最后一个时的边界条件是后一个和当前不相等。否则缩小左边界继续移动。
同类题
代码
public int find(int []nums,int target,boolean isFindFirst){
int left = 0;
int right = nums.length-1;
int mid;
while(left<=right){
mid = left+(right-left)/2;
if(nums[mid]<target){
left = mid+1;
}else if(nums[mid]>target){
right = mid-1;
}else{
//找到目标值,开始定位到第一个和最后一个位置、
//用布尔值确定是查找第一个还是最后一个
if(isFindFirst){
//不满足左边第一个的条件,继续往左找
if(mid>0&&nums[mid]==nums[mid-1]){
right = mid-1;
}
else{
return mid;
}
}
else{
//找最后一个
if(mid<nums.length-1&&nums[mid]==nums[mid+1]){
left = mid+1;
}
else{
return mid;
}
}
}
}
return -1;
}
public int[] searchRange(int[] nums, int target) {
if(nums==null){
return new int[]{-1,-1};
}
int first = find(nums,target,true);
int last = find(nums,target,false);
return new int[]{first,last};
}
public int search(int[] nums, int target) {
//寻找右边界
int left = 0;
int right = nums.length-1;
while(left<=right){
int mid = left+(right-left)/2;
if(nums[mid]<=target) left = mid+1;
else right = mid-1;
}
int rightcur = right;
if(right>=0&&nums[right]!=target) return 0;
//寻找左边界
left = 0;right = nums.length-1;
while(left<=right){
int mid = left+(right-left)/2;
if(nums[mid]<target) left = mid+1;
else right = mid-1;
}
int leftcur = left;
return rightcur-leftcur+1;
}