首页 > 其他分享 >大一计算机的自学总结:二分搜索

大一计算机的自学总结:二分搜索

时间:2025-01-05 15:30:52浏览次数:3  
标签:二分 int ans num 搜索 数组 大一 自学

前言

回顾之前初学循环时写过的猜数小游戏,若范围是0~100,大多数人的猜法都是先猜50,若大了,则猜25;若小了,则猜75......这种搜索方法,就是二分搜索。

一、二分搜索原理

二分搜索的原理很简单,但非常实用。二分搜索时,每次都把有序数组分成两份,判断中点位置的值和要搜索的值的大小关系,然后进行下一步搜索。

二、例题

1.有序数组搜索n

#include<bits/stdc++.h>

using namespace std;

//二分搜索
int search(int num,vector<int>n)
{
	int l=0;
	int r=n.size()-1;
	int m=0;
	
//	int cnt=0;
	while(l<=r)
	{
		m=(l+r)/2;
//		cout<<"m : "<<m<<endl; 
		if(n[m]==num)
		{
//			cout<<cnt+1<<endl;
			return m;
		}
		else if(n[m]>num)
		{
			r=m-1;
		}
		else
		{
			l=m+1;
		}
//		cnt++;
//		cout<<cnt<<"..."<<endl;
	}
	return 0;
}

int main()
{
	vector<int>n;
	for(int i=1;i<=100;i++)
	{
		n.push_back(i);
	}
	
	int num;
	cin>>num;
	
	int result=search(num,n);
	if(result) 
	{
		cout<<"Found In "<<result;
	}
	else
	{
		cout<<"Not Found";
	}
	
	return 0;
}

因为数组有序,所以可以对其使用二分搜索。

首先设置变量l表示起始位置,r表示结束位置,m表示中点位置。

然后,只要当l<=r,即可以继续二分,就判断中点值和搜索值,若相等则返回m;若大于搜索值则让r=m-1;若小于则让l=m+1,然后继续二分,知道搜索到或不存在为止。

2.有序数组返回>=num的最左侧位置

#include<bits/stdc++.h>

using namespace std;

//二分搜索大于等于num的最左侧位置 
int search(int num,vector<int>n)
{
	int l=0;
	int r=n.size()-1;
	int m=0;
	int ans=-1;
	
//	int cnt=0;
	while(l<=r)
	{
		//m=(l+r)/2;
		m=l+(r-l)/2;//防溢出
		
//		cout<<"m:"<<m<<endl;

		if(n[m]>=num)
		{
			ans=m;
			r=m-1;
		} 
		else
		{
			l=m+1;
		}
		
//		cnt++;
//		cout<<cnt<<"..."<<endl;
	}	
	return ans;
} 

int main()
{
	vector<int>n;
	
	for(int i=2;i<=100;i+=2)
	{
		n.push_back(i);
	}
	
	int num;
	cin>>num;
	
	int result=search(num,n);
	if(result!=-1)
	{
		cout<<result;
	}
	else
	{
		cout<<"Not Exist";
	}
	
	return 0;
}

首先,除了l,m,r,还需要设置ans变量来记录位置。这里,l+(r-l)/2同样可以取l和r的中点,其优点是,在l和r特别大时,可以防止数据溢出。

若中点值大于等于num,则更新ans,使其等于此时的中点值;若小于则不更新ans。直到不可继续二分,则循环结束,返回ans。

同理,有序数组返回<=n的最右侧位置类似。

3.无序数组找极大值点

#include<bits/stdc++.h>

using namespace std;

//二分搜索无序数组中的极大值 
int search(vector<int>n)
{
	//先判断端点 
	int len=n.size();
	if(n[0]>n[1])
	{
		return 0;
	}
	if(n[len-1]>n[len-2])
	{
		return len-1;
	}
	
	int l=0;
	int r=len-2;
	int m=0;
	int ans=-1;
	
	while(l<=r)
	{
		m=(l+r)/2;
		
		if(n[m-1]>n[m])
		{
			r=m-1;	
		}
		else if(n[m+1]>n[m])
		{
			l=m+1;	
		}	
		else
		{
			ans=m;
			break;
		}
	} 
	return ans;
}

int main()
{
	vector<int>n;
	int a;
	for(int i=0;i<10;i++)
	{
		cin>>a;
		n.push_back(a);
	}
	
	int result=search(n);
	if(result!=-1)
	{
		cout<<result;
	}
	else
	{
		cout<<"Not Found";
	}
	
	return 0;
}

与之前不同,这里是无序数组,但我们依然可以使用二分搜索。

根据导数的零点存在定理(没想到吧这里也有高数!)可知,在闭区间[a,b]上,若f(a)*f(b)<0,则存在f(x)=0。由此可知,若可以判断两端点的导数之积小于零,即函数趋近两端点的单调性相反,则中间必存在导数为0的点。进一步可知,若导数趋近左端点时大于零,趋近右端点时小于零,则中间必存在极大值点。

所以,我们先判断左右端点是否为极大值。若均不是,根据以上原理则说明中间必存在极大值点。此时,我们就可以使用二分搜索。若m-1的值大于m,则说明中点的左导数小于零,则说明左侧必有极大值;若m+1的值大于m,说明中点的右导数大于零,则说明右侧必有极大值;若均不满足,则此时m点即为极大值点。

总结

即使第三题为无序数组,依然可以使用二分搜索。由此可得,二分搜索的条件可以推广到,只要通过判断某点值和目标值的大小,可以确定该点一侧必存在或一侧必不存在目标值,就可以使用二分搜索。

END

标签:二分,int,ans,num,搜索,数组,大一,自学
From: https://blog.csdn.net/2402_89326161/article/details/144908943

相关文章

  • 什么是数据运营(自学记录)
    1.总结跟普通运营一样都是产品和用户之间的枢纽,不过更偏向于对数据进行分析。2.干什么的运用数据来指导决策、实现业务增长。侧重支持业务决策、互联网运营等类别。根据维度的不同对用户进行层级划分。具体:1.AARRR(具体内容大家可以看AARRR模型最详解-知乎)用户获取(Ac......
  • 【C语言】数组——二分查找
    题1704.二分查找【简单】intsearch(int*nums,intnumsSize,inttarget){intleft=0,right=numsSize-1;intmid=(left+right)/2;intresult=-1;while(left<=right){if(nums[mid]==target){r......
  • 网络安全(黑客)自学
    ......
  • 二分 + 倍增 做题笔记
    一些关于二分和倍增的题,大体按照题目难度排序。1.CF1951HThanosSnap简要题意给定一个长为\(2^n\)的序列\(a_0,a_1,\cdots,a_{2^n-1}\),对所有\(t\in[1,n]\)求解如下问题:A和B两人在序列\(a\)上博弈,一共进行\(t\)轮操作。每轮操作的流程如下:A可以选......
  • Final Boss(二分答案)
    原题链接:Problem-F-Codeforces思路:二分答案代码:#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;constintxmmm=2e5+10;inta[xmmm],b[xmmm];intn,m;intcheck(intx){intsum=0;for(inti=1;i<=n;i++){sum+=(1+(x-......
  • 二分查找 - 相关基础算法总结
    问题1:寻找target位置,没有返回-1问题2:从右往左,寻找<target的第一个位置问题3:从左往右,寻找>target的第一个位置问题4:从右往左,寻找<=target的第一个位置问题5:从左往右,寻找>=target的第一个位置以上问题是求很多解力扣算法题的基础,需要好好的掌握: 问题1:寻找......
  • 【优选算法】Binary-Blade:二分查找的算法刃(下)
    文章目录1.山脉数组的峰顶索引2.寻找峰值3.寻找旋转排序数组中的最小值4.点名希望读者们多多三连支持小编会继续更新你们的鼓励就是我前进的动力!本篇接上一篇二分查找,主要通过部分题目熟悉二分查找的进阶使用,重点强调二段性,找到两个区间不同的地方在哪,多画图划分界限......
  • 如何使用建筑物变化检测算法的Baseline工程 ,使用PyTorch框架,并选择U-Net来进行二分类
    建筑物变化检测算法baseline工程使用PyTorch框架,并选择U-Net来进行二分类任务(变化/不变)Baseline工程将基于深度学习方法来检测建筑物的变化备注:博客所有文章代码仅供参考!如何使用建筑物变化检测算法的Baseline工程,一个详细的步骤和代码示例。这个Baseline工程将基于深......
  • Python-二分法的进阶与Bisect库详解
    1.1前言:在进阶之前可能很多学过二分法的人都认为二分查找十分简单,但事实不完全如此。比如你是否熟练的知道while的条件有等于时返回究竟是mid还是left,还是right,还是随便返回一个没有等于时又是返回什么……本文将给大家讲解二分法的进阶和bisect库函数的运用,并且再讲解之后......
  • 有很多同学问快到期末了怎么办?人工智能本科大一该怎么过?
    大家好,我是天海。过完了人工智能本科四年的“摸着石头过河”的大学生活,我的这些经验希望能够帮到你。我将推荐一些大学期间的打怪升级的成长路线供大家参考。大一:学习好基础课拿绩点、学习一些编程语言、可以适当参加社团、学生会。1、大一上学期在刚入学后,学校是会有一场......