leetcode.704. 二分查找(三种解法!)

二分查找的前提:数组,排列好顺序,无重复元素。

二分查找关键:left,right的初始化

                        while循环的循环条件

                        while循环中left,right的赋值;

二分查找围绕while循环的循环条件进行展开:

        1:left<=rigth

        2:left<rigth

当while(left<=right)时

        我们默认middle=(left+right)/2;

1.考虑极端条件下的初始化:left,right是否能进入循环?

        当nums.size()=1,left=0,right=nums.size()-1时:

        判定left==right==0能够进入循环,满足初始化条件

2.考虑极端条件下能否退出循环,即当left==right且没有找到目标值时,如何退出循环?       

        此时middle=0,left=0,right=0;

        理所当然需要left=middle+1,right=middle-1才能退出循环

则代码如下:

class Solution {
public:
    int search(vector<int>& nums, int target) {
		int left=0,right=nums.size()-1;
		while(left<=right){
			int middle=left+((right-left)>>1);
			if(nums[middle]>target) right=middle-1;
			else if(nums[middle]<target) left=middle+1;
			else return middle;
		}
		return -1;
    }
};

当while(left<right)时

        我们默认middle=(left+right)/2;

1.考虑极端条件下的初始化:left,right是否能进入循环?

        当nums.size()=1,left=0,right=nums.size()-1时:

        此时right=0,判定left==right,不能进入循环,说明初始化错误!

        我们进行如下修改right=nums.size();

        此时right=1,判定left<right,可以进入循环,初始化成功!

 2.考虑极端条件下能否退出循环?

        当left=n,right=n+1,此时middle=n:

        假设没有找到目标值,理所当然需要left=middle+1,right=middle;

        

class Solution {
public:
    int search(vector<int>& nums, int target) {
		int left=0,right=nums.size();
		while(left<right){
			int middle=left+(right-left)/2;
			if(target<nums[middle]) right=middle;
			else if(nums[middle]<target) left=middle+1;
			else return middle;
		}
		return -1;
    }
};

        这就是我们的左闭右开式二分查找!

放出左开右闭式二分查找代码:

class Solution {
public:
    int search(vector<int>& nums, int target) {
		int left=-1,right=nums.size()-1;
		while(left<right){
			int middle=left+(right-left)/2+1;
			if(target<nums[middle]) right=middle-1;
			else if(nums[middle]<target) left=middle;
			else return middle;
		}
		return -1;
    }
};

备注:

        >>1是移位运算;

        left+(right-left)/2是防止溢出;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值