二分查找算法
现在有一个从小到大排序的数组,给你一个目标值target,现在请你找到这个值在数组中的对应下标,如果没有,请返回-1:
`int search(int* nums, int numsSize, int target){
//请实现查找算法
}
int main() {
int arr[] = {1, 3, 4, 6, 7,8, 10, 11, 13, 15}, target = 3;
printf("%d", search(arr, 10, target));
}
`
此时,最简单的方法就是将数组中的元素一个一个进行遍历,总有一个是,如果遍历完后一个都没有,那么就结束:
int search(int* nums, int numsSize, int target){
for (int i = 0; i < len; ++i) {
if(nums[i] == target) return i; //循环n次,直到找到为止
}
return -1;
}
虽然这样的算法简单粗暴,但是并不是最好的,我们需要遍历n次才能得到结果,时间复杂度为O ( n ),我们可以尝试将其优化到更低的时间复杂度。这里我们利用它有序的特性,实际上当我们查找到大于目标target的数时,就没必要继续寻找了:
int search(int* nums, int numsSize, int target){
for (int i = 0; i < len; ++i) {
if(nums[i] == target) return i;
if(nums[i] > target) break;
}
return -1;
}
这样循环进行的次数也许就会减小了,但是如果我们要寻找的目标target刚好是最后几个元素呢?这时时间复杂度又来到到了O ( n )
那我们可以对半查找,如果中间数比要目标大,对半选左边部分,如果中间数target比目标小,对半选右边部分。
然后继续在另一部分中再次随机找一个数,这样每次都能将范围缩小,直到找到为止(其思想就比较类似于牛顿迭代法,再次强调数学的重要性)
我们采用递归分治算法:
代码如下:
int a(int* nums,int target,int left,int right){
if(left > right) return -1;
int mid = (left + right) / 2;
if(nums[mid] == target) return mid;
if(nums[mid] > target)
return a(nums,target,left,mid - 1);
else
return a(nums,target,mid + 1,right);
}
int search(int* nums,int numsSize,int target)
{
return a(nums,target,0,numsSize - 1);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了