二分查找--最清晰简洁明了的解法!!

上力扣原题目链接:704. 二分查找 - 力扣(LeetCode)

为了方便大家查看,我这边列出题目描述

题目描述:

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

示例:

输入: 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

输入: nums = [5], target = 5
输出: 0

首先先解释一下为什么力扣没有主函数,这是为了让大家更加有效率的刷题而设计的,我们只需在它给出来的类函数里面利用它已知的条件书写就可以了。

(本题的前提是数组内没有重复的元素,否则返回的下标不是唯一的)

解法:

先把数组元素sort排序一下,按升序排序。如果输入样例已经排好了,则可以省略这个步骤。

先设三个变量l,r,mid并初始化,分别代表最初数组的最左边,最右边和最中间的数组下标,这里因为数组的下标是从0开始的,所以l=0,r=nums.size()-1,mid=(l+r)/2。

因为需要不断的把数组二分化,再进行查找,所以mid赋值和查找需要在循环里进行。这里的循环条件是l的下标不大于r。

循环内面临三种情况,先对比是否nums[mid]==target,如果nums[mid]的值等于我们要查找的值,就直接返回mid下标;如果不等于,则再进行下面的两种情况对比。

  1. 一种是nums[mid]>target,由于数组是升序,则表示target在mid下标的左边,这时候应该把搜索区间选为左半边的数组,则需要把r改为mid-1,然后再进行循环查找。
  2. 一种是nums[mid]<target,由于数组是升序,则表示target在mid下标的右边,这时候应该把搜索区间选为右半边的数组,则需要把l改为mid+1,然后再进行循环查找。

关于为什么循环条件是l<=r
因为如果不设置l<=r,那么当数组中只有一个元素时,l=0,r=0,这时候不会进入循环,而会返回一个-1,无法通过所有案例。

话不多说,我们直接看代码

class Solution {
	public:
	int search(vector<int>& nums, int target) {
		int l=0,r=nums.size()-1;
		int mid;
		while(l<=r){
			mid=(l+r)/2;
			if(nums[mid]==target){
				return mid;
			}else if(nums[mid]<target){
				l=mid+1;
			}else if(nums[mid]>target){	
				r=mid-1;
			}
		}
		return -1;
	}
};
为什么要选择二分查找?

二分查找的好处就是不用一个一个去对比是否为要求元素,而是把数组逐渐分成两半去寻找

,时间复杂度从最原始的O(n)降到了O(logn)


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值