[質問の再開] 34。昇順で配置された整数配列numとターゲット値ターゲットを指定して、ソートされた配列内の要素の最初と最後の位置を見つけます。配列内の指定されたターゲット値の開始位置と終了位置を見つけます。

トピック: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;
}

おすすめ

転載: blog.csdn.net/m0_46613023/article/details/113938943