力扣网C语言编程题:在数组中查找目标值位置

一. 简介

本文记录一下力扣网上涉及数组的问题:排序数组中查找目标值的位置。主要以C语言实现。

二. 力扣网C语言编程题:在数组中查找目标值位置

题目:在排序数组中查找元素的第一个和最后一个位置

给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。

示例 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]

提示:
    0 <= nums.length <= 105
    -109 <= nums[i] <= 109
    nums 是一个非递减数组
    -109 <= target <= 109

题目分析:

首先,题目提到数组是非递减序列,就是说从左到右元素是不严格递增的,即每个元素大于或等于前一个元素。

其次,题目要求方法的时间复杂度必须是  O(log n)。

结合上面的信息可推测,本题目可能是要求使用二分查找法来实现。

1. 解题思路一(暴力解法):

利用数组有序的特点从头到尾遍历一遍数组(相等的元素都在一起)。

暴力解法就是直接遍历数组,找到 target第一次出现的位置和最后一次出现的位置。

这种解法的其实不满足题目要求的,因为这种方法的时间复杂度是 O(n),已经超过 O(log n)。

具体方法如下:

(1) 动态申请一段内存存放返回的数据(只要 存储2个元素的缓存即可);首先,缓存中元素都赋值为 -1;

(2) 遍历数组,判断 nums[i] 是否等于 target:

如果nums[i] 等于 target:再判断 ret_ptr[0] 是否为初始值(确认是否是第一次出现的位置);

ret_ptr[0] 是初始值:则记录元素Index:ret_ptr[0] = index;ret_ptr[0] 不是初始值,则将当前的 index值更新到ret_ptr[1]: ret_ptr[1] = index;

C语言实现如下:

//暴力解法
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* searchRange(int* nums, int numsSize, int target, int* returnSize) {
    int i;
    int* ret_ptr = (int*)malloc(2* sizeof(int));
    ret_ptr[0] = -1;
    ret_ptr[1] = -1;
    
    if((nums == NULL) || (numsSize <= 0) || (returnSize == NULL)){
        return ret_ptr;
    }

    *returnSize = 2;
    for(i = 0; i < numsSize; i++) {
        if(nums[i] == target) {
            if(ret_ptr[0] == -1) { //判断是否是第一次出现的位置,是则记录下元素的index
                ret_ptr[0] = i;
            }
            ret_ptr[1] = i; //记录最后一次出现的位置
        }
    }

    return ret_ptr;
}

这里实现上注意,当数组为空时,处理上返回了 申请的内存指针(但是这里内存也赋了初始值),而不是返回NULL。这样做比较合适。

上面实现方法虽然编译通过,但是该实现方法时间复杂度为 O(n),不满足题目要求。

2. 解题思路二:(二分查找法)

题目说数组是非递减序列,也就是说数组元素从左到右元素是不严格递增的,即每个元素大于或等于前一个元素。有序序列中查找一个目标值,符合 "二分查找法" 的特点。

C语言实现如下:

可以看出,二分查找法

你可能感兴趣的:(逻辑编程题,C语言,算法,c语言,leetcode)