トピック:34。ソートされた配列内の要素の最初と最後の位置を見つける
昇順で配置された整数配列numsと、ターゲット値targetが与えられます。配列内の指定されたターゲット値の開始位置と終了位置を見つけます。
ターゲット値targetが配列に存在しない場合は、[-1、-1]を返します。
回答:
方法1:直感的なアイデアは、間違いなく前から後ろにトラバースすることです。検出された最初と最後の添え字を記録するために2つの変数が使用されますが、このメソッドの時間計算量はO(n)O(n)であり、配列の昇順の条件は使用されません。
int* searchRange(int* nums, int numsSize, int target, int* returnSize)
{
// 开辟两个int大小的空间放索引
int* res = (int*)malloc(sizeof(int) * 2);
// 判断是否找到target
int flag = 0;
int i = 0;
while (i < numsSize)
{
// 找到target,flag置1
if (nums[i] == target)
{
flag = 1;
break;
}
i++;
}
// 没找到target,返回[-1,-1]
if (flag == 0)
{
res[0] = -1;
res[1] = -1;
*returnSize=2;
return res;
}
// 程序走到这里,一定存在索引
// 先记录第一个索引位置
res[0] = i;
// 寻找结束位置
while (i < numsSize && nums[i] == target)
{
i++;
}
// 再记录结束索引位置
res[1] = i - 1;
*returnSize=2;
return res;
}
方法2:配列が並べ替えられているため、配列全体が単調に増加しています。二分法を使用して、検索プロセスを高速化できます。
実際、私たちが探しているのは、配列内の「ターゲットに等しい最初の位置」と「ターゲットから1より大きい最初の位置」です。
// 找出给定目标值在数组中的开始位置
int findFitstPosition(int* nums, int numsSize, int target)
{
int size = numsSize;
int left = 0;
int right = size - 1;
while (left < right)
{
// 取下界
int mid = left + (right - left) / 2;
if (nums[mid] < target)
left = mid + 1;
else if (nums[mid] == target)
// 即使nums[mid] == target,也要right = mid
// 使得下标向target的第一个位置靠拢
right = mid;
else
// nums[mid] > target
right = mid - 1;
}
// left == right
if (nums[left] != target)
return -1;
return left;
}
// 找出给定目标值在数组中的结束位置
int findLastPosition(int* nums, int numsSize, int target)
{
int size = numsSize;
int left = 0;
int right = size - 1;
while (left < right)
{
// 取上界
int mid = left + (right - left + 1) / 2;
if (nums[mid] > target)
right = mid - 1;
else if (nums[mid] == target)
// 使得下标向target的最后一个位置靠拢
left = mid;
else
// nums[mid] < target
left = mid + 1;
}
// left == right
if (nums[left] != target)
return -1;
return left;
}
// 在排序数组中查找元素的第一个和最后一个位置
int* searchRange(int* nums, int numsSize, int target, int* returnSize)
{
int* ans=(int*)malloc(sizeof(int)*2);
int size = numsSize;
// 整数数组为空,直接返回[-1,-1]
if (size == 0)
{
ans[0]=-1;
ans[1]=-1;
*returnSize=2;
return ans;
}
// 没有找到target,,直接返回[-1,-1]
int fitstPosition = findFitstPosition(nums, numsSize, target);
if (fitstPosition == -1)
{
ans[0]=-1;
ans[1]=-1;
*returnSize=2;
return ans;
}
int lastPosition = findLastPosition(nums, numsSize, target);
ans[0]=fitstPosition;
ans[1]=lastPosition;
*returnSize=2;
return ans;
}
// 找出给定目标值在数组中的开始位置
int findFitstPosition(int* nums, int numsSize, int target)
{
if(numsSize==0)
return -1;
int size = numsSize;
int left = 0;
int right = size - 1;
while (left < right)
{
// 取下界
int mid = left + (right - left) / 2;
if (nums[mid] < target)
left = mid + 1;
else if (nums[mid] == target)
// 即使nums[mid] == target,也要right = mid
// 使得下标向target的第一个位置靠拢
right = mid;
else
// nums[mid] > target
right = mid - 1;
}
// left == right
if (nums[left] != target)
return -1;
return left;
}
// 找出给定目标值在数组中的结束位置
int findLastPosition(int* nums, int numsSize, int target)
{
if(numsSize==0)
return -1;
int size = numsSize;
int left = 0;
int right = size - 1;
while (left < right)
{
// 取上界
int mid = left + (right - left + 1) / 2;
if (nums[mid] > target)
right = mid - 1;
else if (nums[mid] == target)
// 使得下标向target的最后一个位置靠拢
left = mid;
else
// nums[mid] < target
left = mid + 1;
}
// left == right
if (nums[left] != target)
return -1;
return left;
}
// 在排序数组中查找元素的第一个和最后一个位置
int* searchRange(int* nums, int numsSize, int target, int* returnSize)
{
int* ans=(int*)malloc(sizeof(int)*2);
int size = numsSize;
int fitstPosition = findFitstPosition(nums, numsSize, target);
// 整数数组为空 或者 没有找到target
// 直接返回[-1,-1]
// 两种情况放在一起的话,前面的两个函数要先排除size=0的情况
// 否则 right = size-1 < 0
// 代码复用,更加简洁
if (size == 0 || fitstPosition == -1)
{
ans[0]=-1;
ans[1]=-1;
*returnSize=2;
return ans;
}
int lastPosition = findLastPosition(nums, numsSize, target);
ans[0]=fitstPosition;
ans[1]=lastPosition;
*returnSize=2;
return ans;
}