二分查找
二分查找
初始查找范围在整个数组 [left,right] ,每次取查找范围的中点 mid ,比较 num[mid] 和target ,如果 它俩相等,则 mid 就是要找的下标;如果不相等则根据它们关系将查找范围缩小一半。
1、使用条件:
- 有序数组;
- 该数组中无重复元素
2、问题
给定一有序整型数组 nums[n] 和一个目标值 target ,这里假设是升序;
要求:搜索nums 中的 target ,如果目标值存在,则返回下标,否则返回 -1。
题目链接:https://leetcode-cn.com/problems/binary-search
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4
输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1
3、分析
数组有序,无重复元素,一旦出现重复元素,返回下标可能不唯一;
写二分法,区间的定义一般为两种,左闭右闭即[left, right],
或者左闭右开即[left, right)。
4、代码
//法一: [left,right]
public int search(int[] nums,int target){
// 考虑target 超出搜索数组范围
if (target < nums[0] || target > nums[nums.length-1]){
return -1;
}
// 当数组有n 个元素,不知道要执行多少次,想到用while
// 定义target在左闭右闭的区间里,[left, right]:
int left = 0;
int right = nums.length - 1;
while (left <= right){
int mid = left + (right - left)/2;
// 防止溢出 等同于(left + right)/2
if (nums[mid] == target){
return mid;
}else if (nums[mid] < target){
// 中间值在目标值的左边,
left = mid + 1;
// 缩小区间为[mid + 1,right]
}else if (nums[mid] > target){
// 中间值在目标值的右边,
right = mid - 1;
// 缩小区间为[left,mid-1]
}
}
// 没找到target
return -1;
//法二: [left,right)
public int search(int[] nums,int target){
// 定义target在左闭右开的区间里,[left, right):
int left = 0;
int right = nums.length; /* 和法一的区别 */
while (left < right){
int mid = left + (right - left)/2;
if (nums[mid] == target){
return mid;
}else if (nums[mid] < target){
// 中间值在目标值的左边,
left = mid + 1;
// 缩小区间为[mid+1,right)
}else if (nums[mid] > target){
// 中间值在目标值的右边,
right = mid; /* 这里和法一的区别 */
// 缩小区间为[left,mid)
}
}
// 没找到target
return -1;
}
5、总结
这里有几点需要注意:
1、target 的两个定义区间的范围不同:
- (target范围和数组范围不一样!!!)
- 当在左闭右闭时,[left,right] = [0,num.length-1]
- 在左闭右开时,[left,right) = [0,num.length)
2、注意不同区间时循环条件:(为什么要考虑两个区间呢???)
- [left,right] 时,while ( left <= right )
- [left,right) 时,while ( left < right )
3、注意两区间下,
当 nums[mid] > target 时,
- 在 [left,right] ,搜索区间变为 [ left,mid-1]
- 在 [left,right),搜索区间变为 [ left,mid)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY