【备战蓝桥,冲击省一】 二分查找法 看完你就会了

目录

一、猜数字

🌸简单查找

🌸二分查找法

 二、二分查找法介绍

🌸固定模板

🌸二分法时间复杂度

三、练习:

🌸力扣704. 二分查找

🌸力扣35. 搜索插入位置

🌸力扣167. 两数之和 II - 输入有序数组


一、猜数字

我随便想一个1~100的数字,你的目标是以最小的次数猜到这个数字。你每一次猜测后,我都会说小了、大了或对了。

🌸简单查找

最简单的方法,就是你从1开始依次往上猜,每一次查找只能排除一个数字。

是1吗?                                                                 小了      

123......100

 

 是2吗?                                                                   小了      

123......100

如果我想的数字是99,那么你需要猜99次才能猜到。显而易见的,这是一种很愚蠢的查找方法。

🌸二分查找法

这是一种更好的猜法,第一个数猜50。

  是50吗?                                                                 小了      

1...5051...100

虽然没有猜中,但是你一下排除了一半的数字!你知道1~50都小了,接下来,你猜75(50和100中间的数)

   是75吗?                                                                         大了      

505150...7475

大了,剩下的数字又排除了一半!接下来,你猜63(50和75中间的数)。

   是63吗?                                                                      对了      

这就是二分查找法,恭喜你已经学会了!在这个游戏中,每次猜测排除的数字个数如下

不管我心中想到哪个数字,你都可以在7步之内猜到,这就是二分查找法的优点。

二分查找法,每次都能排除一半的数字

我们试一试用代码表示:

#include<stdio.h>
int main()
{
	int l=0,r=100,target;
	scanf("%d",&target);
	while (l < r)
	{
	    int mid =(r-l)/2+l;
	    if(mid==target)
	    {
			printf("你的数字为%d",mid);
			return 0;
		}
	    else if (mid>target)
		{
			r=mid-1;
		}      
		else
		{
			l=mid+1;
		}
	}
}

 二、二分查找法介绍

🌸固定模板

我们来看一看二分法的固定模板

int binarySearch(vector<int> nums, int left, int right, int x)
{
       int mid;//mid为中点
       while (left<=right)
       {
              mid = left + (right - left) / 2;//取中点
              if (nums[mid] == x) return mid;// 找到x,返回下标
              else if (nums[mid]>x)//中间的数大于x
              {
                    right = mid - 1;//往左子区间[left,mid-1]查找
              }
			  else 					//中间的数小于x
			  {
                    left = mid + 1; //往右子区间[mid+1,right]查找
              }
       }
       return -1;//查找失败,返回-1
}

 为什么用【mid = left + (right - left)/2】而不用【mid=(right+left)/2-left】呢?

当left和right都很大的时候,可能会造成越界

我们可以这样理解二分查找法

【left,right】—— 用于标记观察查找范围的位置

【while (left<=right)】—— 只要范围没有缩小到只剩一个元素就继续查找

【 if (nums[mid]>x) 】—— 若中间值大于目标值——【right = mid - 1;】改变右端点,往左子区间[left,mid-1]查找

【 if (nums[mid]<x) 】—— 若中间值小于目标值——【left = mid + 1;】改变左端点,往右子区间[mid+1,right]查找

🌸二分法时间复杂度

一般而言,对于包含n个元素的列表,用简单查找最多需要n步,用二分查找法最多需要log2n步。

二分查找法的运行时间为对数时间,是一种很高效的算法。

三、练习:

🌸力扣704. 二分查找

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

🌸力扣35. 搜索插入位置

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int n = nums.size();
        int l=0,r=n-1;
        while(l<=r){
            int mid=l+(r-l)/2;
            if(nums[mid]<target)
                l=mid+1;
            else r=mid-1;
        }
        return l;
    }
};

🌸力扣167. 两数之和 II - 输入有序数组

class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        for(int i=0;i<numbers.size();i++)
        {
            int left=i+1,right=numbers.size()-1;
            while(left<=right)
            {
                int mid=(right-left)/2+left;
                if(numbers[i]+numbers[mid]==target)
                {
                     return {i+1,mid+1};
                }
                else if(numbers[i]+numbers[mid]>target)
                {
                    right=mid-1;
                }
                else
                {
                    left=mid+1;
                }
            }
        }
        return {-1, -1};
    }
};
  • 54
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 74
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

锡兰_CC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值