一. 简介
本文记录一下力扣网上涉及数组的问题:排序数组中查找目标值的位置。主要以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) { //判断是否是第一次出现的位置,是则记录下元素的indexret_ptr[0] = i;}ret_ptr[1] = i; //记录最后一次出现的位置}}return ret_ptr;
}
这里实现上注意,当数组为空时,处理上返回了 申请的内存指针(但是这里内存也赋了初始值),而不是返回NULL。这样做比较合适。
上面实现方法虽然编译通过,但是该实现方法时间复杂度为 O(n),不满足题目要求。
下一篇文章使用二分查找法进行实现,因为二分查找法符合题目要求(时间复杂度为O(log n))。