一、题目描述:
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
难度:简单。
示例1:
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4
示例2:
输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1
提示:
- 你可以假设 nums 中的所有元素是不重复的。
- n 将在
[1, 10000]之间。 - nums 的每个元素都将在
[-9999, 9999]之间。
相关知识:二分查找。
二、思路分析:
考察点与思想
这道题考察的点很简单,是算法里面比较常见的二分查找,也就是考察对二分法的理解。
二分查找一般有以下步骤:
- 预处理-如果待求解数组未排序,则需要考虑先进行排序;
- 二分查找-使用循环或递归在每次比较后将查找空间划分为两半;
- 后处理-继续在剩余空间中确定可行的候选者。
思路和问题
做题时,思路并不难理解,基于二分法。
- 每次取数组中间值 mid 与目标值 target 进行比较;
- 如果 target == mid,则说明找到目标值,直接返回结果;
- 如果 target > mid,则说明目标值在右区间,要收缩左边界,则 left = mid + 1;
- 反之,说明目标值在左区间,收缩右边界,则 right = mid - 1;
- 继续循环 2-4 步,直到 left > right 时结束循环;
- 如果搜索区间中存在目标值,则会在循环中返回,如果循环结束还找不到,说明不存在,返回 -1。
其中的关键点是要把握好各个边界点。
- 循环结束的点,left 和 right 相等时也是处于求解区间的,所以得继续循环;
- 假设目标值处于求解区间,则在结束循环后是已经返回解了;
- 如果不存在,需要返回 -1。
三、AC 代码:
int search(int* nums, int numsSize, int target){
// 查找区间[left,right]
int l = 0;
int r = numsSize - 1;
int mid = 0;
while(l <= r) {
mid = l + (r-l)/2;
if(target == nums[mid]) {return mid;}
if(target > nums[mid]) {
l = mid+1;
}else {
r = mid-1;
}
}
return -1;
}
四、总结:
这个算法是简单的二分查找,通过寻找目标值得到求解。
但是在实际情况下,可能不总是直接搜索特定值,有可能会以让你寻找最左/右边满足条件的值、寻找最左/右插入位置,或者让你在局部有序的数组中寻找满足条件的值等多种形式出现。
但是万变不离其宗,核心思想都是尽量在每次处理后都将问题的规模缩小到原来的一半,直到得到满足条件的解或者超出边界。
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情