给你一个按照非递减顺序排列的整数数组 nums
,和一个目标值 target
。请你找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target
,返回 [-1, -1]
。
示例 1:
输入:nums = [5,7,7,8,8,10], target = 8 输出:[3,4]示例 2:
输入:nums = [5,7,7,8,8,10], target = 6 输出:[-1,-1]示例 3:
输入:nums = [], target = 0 输出:[-1,-1]
二分查找,能采用二分查找的题,基本都是要排序好的,无论是 非递减 或者 非递增。
同志们可以先了解2分查找,再先试着做这道题,最后再看我的。
废话不多说,二分查找的基本题,直接上代码。
#include <stdio.h>
#include <stdlib.h>
//二分查找 在数组中查找元素第一个和最后一个位置
int* searchRange(int* nums, int numsSize, int target, int* returnSize)
{
int left, right, mid;
int *p = malloc(sizeof(int) * 2);//开辟空间 不能直接用 sizeof(returnSize),returnSize表示的是地址,这样获取到的就是地址的大小
p[0] = p[1] = -1; //一开始默认没有找到为-1
if(numsSize == 0)//如果数组没有元素
{
return p;
}
if(numsSize == 1)//如果数组只有一个元素
{
(nums[0] == target) ? (p[0] = p[1] = 0) : (p[0] = p[1] = -1);
return p;
}
left = 0, right = numsSize-1, mid = (left + right) / 2;
while(left <= right)//计算第一次出现的坐标
{
if(nums[mid] == target)//出现一次就覆盖一次 出现的左值
{
p[0] = mid;
right = mid - 1;//往左边找
mid = (left + right) / 2;
}
else if(nums[mid] < target)
{
left = mid + 1;
mid = (left + right) / 2;
}
else if(nums[mid] > target)
{
right = mid - 1;
mid = (left + right) / 2;
}
}
left = 0, right = numsSize-1, mid = (left + right) / 2;
while(left <= right)//计算最后一次出现的右值
{
if(nums[mid] == target)
{
p[1] = mid;
left = mid + 1;//往右边找
mid = (left + right) / 2;
}
if(nums[mid] < target)
{
left = mid + 1;
mid = (left + right) / 2;
}
else if(nums[mid] > target)
{
right = mid - 1;
mid = (left + right) / 2;
}
}
return p;
}
int main()
{
int nums[] = {5, 7, 7, 8, 8, 10};
int numssize = sizeof(nums) / sizeof (nums[0]);
int target = 7;
int returnSize[2];
int *pst = searchRange(nums, numssize, target, returnSize);
printf("%d %d",pst[0],pst[1]);
}