一、题目描述与要求
题目描述:
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。
示例:
输入: nums = [1,3,5,6], target = 5
输出: 2
输入: nums = [1,3,5,6], target = 2
输出: 1
输入: nums = [1,3,5,6], target = 7
输出: 4
提示:
1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums 为 无重复元素 的 升序 排列数组
-104 <= target <= 104
二、解题思路
总的思路:
给定一个排序数组和一个目标值,并且在数组中查找,那就需要将这个目标值与数组中的每一个元素进行比较,如果存在则返回对应下标,如果不存在的话就要返回按顺序插入的位置。首先先判断数组元素个数是否==0,是的话直接返回0;判断target是否比数组的最后一个数要大,因为是有序数列,所以比他大的话就插入后面,返回numsSize.比较与插入的话有两种思路,一种是一整个数组进行循环,但是在找不到进行插入的时候可能要将后面的元素进行后移,这就需要调用两个for循环进行嵌套,这样的话时间复杂度就与题目要求不符合。第二种就是二分查找法,在一定程度上提高效率,设定左右中三个指针,然后将nums[mid]与target进行比较,如果相等则返回mid,不相等则看比nums[mid]小还是大,小的话让high=mid-1,将查找范围缩小到目前mid前半部分,如果大就让left=mid+1,将查找范围缩小到目前mid后半部分,查找完毕后,返回left就是其对应的坐标。注意每次变换范围之后,mid都要进行变化,所以mid=(left+right)/2是放在while循环里面的。
具体步骤:
1、判断数组是否为空
2、判断目标值是否大于数组中所有元素
3、定义left、right和mid作为工作指针(指示下标)
4、判断nums[mid]是否等于target,等直接return mid
5、判断nums[mid]大于还是小于target从而对查找范围进行缩小直至left>right或者找到,return left。
三、具体代码
int searchInsert(int* nums, int numsSize, int target){
if(numsSize==0)
return 0;
if(target>nums[numsSize-1])
return numsSize;
int left=0;
int right=numsSize-1;
while(left<=right)
{
int mid=(left+right)/2;
if(nums[mid]==target)
return mid;
else if(nums[mid]>target)
{
right=mid-1;
}
else
{
left=mid+1;
}
}
return left;
}