二分查找 c++

一.前言

二分法:理解十分的容易,但就是一学就会,一写就废,总会把区间问题搞错,进而导致最后的结果不对。我会以一种记录自己学习方式的形式来总结一下二分法的区间问题,有不对的可以相互探讨加以改正😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄
[low,high]左闭右闭
[low,high)左闭右开
二分法求的目标值 默认在有序递增的素组中

  • 取值问题

在c/c++中的取值都是向下取整,所以数组的奇数和偶数都可以取到mid值

例题

在这里插入图片描述
704.二分查找-力扣

二.分查找的两种范围

1.左闭右闭

  • [low,high]
分析:
  • 因为左闭右闭,所以int low=0;
    int high=nums.size()-1;
int low=0;
int high=nums.size()-1;
  • [low,high] 左闭右闭区间范围,及low和high的关系可以存在一个合法的公式low<=high
    例如:[1.1]在low<=high是一个合法的范围
while(low<=high)
  • 如果mid小于target那么low要更新初始值
  • 但mid已经小于target了,所以当low=mid不符合条件,
    因此low=mid+1
    左闭右闭 的思想中明确指出low是一个可取到的值)
if(nums[mid]<target)
		{
			low=mid+1;
		}

在这里插入图片描述

  • 同理:
    如果mid大于target那么high要更新初始值
    但mid已经大于target了,所以当high=mid不符合条件,
    因此high=mid-1
    左闭右闭 的思想中明确指出high是一个可取到的值)
if(nums[mid]>target)
		{
			high=mid-1;
		}

在这里插入图片描述

  • 最后一个mid=target,直接返回mid
if(nums[mid]==target){
			return mid; 
		}
代码力扣编号704题[左闭右闭]:
class Solution {
public:
 int search(vector<int>& nums, int target)
{
	int low=0;
	int high=nums.size()-1;
	while(low<=high)
	{
		int mid=(low+high)/2;
		if(nums[mid]==target){
			return mid; 
		}
		else if(nums[mid]>target)
		{
			high=mid-1;
		}
		else if(nums[mid]<target)
		{
			low=mid+1;
		}
	}
     return -1;//未找到数值,这个要放到while循环的外面,避免报错
}
};

dev完整代码c++

#include<bits/stdc++.h>
using namespace std;
 int search(vector<int>& nums, int target)
{
	int low=0;
	int high=nums.size()-1;
	while(low<=high)
	{
		int mid=(low+high)/2;
		if(nums[mid]==target){
			return mid; 
		}
		else if(nums[mid]>target)
		{
			high=mid-1;
		}
		else if(nums[mid]<target)
		{
			low=mid+1;
		}
	}
     return -1;
}


int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int n;
	cin>>n;
	vector<int>a(n);
	for(int i=0; i<n; i++)
	{
		cin>>a[i];
	}
	int target;
	cin>>target;
	int m= search(a,target);
	cout<<m<<endl;
	return 0;
}

2.左闭右开

  • [low,high)
分析:
  • 因为左闭右开,所以int low=0;
    int high=nums.size();
    high不包含最后一个数据
int low=0;
int high=nums.size();
  • [low,high) 取不到high的数值,所以low<=high中的low=high没有意义
    例如:[1.2) 右侧的2取不到,只能取到小于2的数
while(low<high)
  • 如果mid小于target那么low要更新初始值
  • 但mid已经小于target了,所以当low=mid不符合条件,
    因此low=mid+1
    左闭右开 的思想中明确指出low是一个可取到的值)
if(nums[mid]<target)
		{
			low=mid+1;
		}

在这里插入图片描述

  • 如果mid大于target那么high要更新初始值
    所以high=mid
    左闭右开 的思想中明确指出high是一个不可取 的值)
if(nums[mid]>target)
		{
			high=mid;//右开,high取不到
		}

在这里插入图片描述

  • 最后一个mid=target,直接返回mid
if(nums[mid]==target){
			return mid; 
		}
代码力扣编号704题[左闭右开]
class Solution {
public:
 int search(vector<int>& nums, int target)
{
	int low=0;
	int high=nums.size();
	while(low<high)
	{
		int mid=(low+high)/2;
		if(nums[mid]==target){
			return mid; 
		}
		else if(nums[mid]>target)
		{
			high=mid;
		}
		else if(nums[mid]<target)
		{
			low=mid+1;
		}
	}
     return -1;
}
};
  • dev完整代码c++代码
#include<bits/stdc++.h>
using namespace std;
 int search(vector<int>& nums, int target)
{
	int low=0;
	int high=nums.size();
	while(low<high)
	{
		int mid=(low+high)/2;
		if(nums[mid]==target){
			return mid; 
		}
		else if(nums[mid]>target)
		{
			high=mid;
		}
		else if(nums[mid]<target)
		{
			low=mid+1;
		}
	}
     return -1;
}


int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int n;
	cin>>n;
	vector<int>a(n);
	for(int i=0; i<n; i++)
	{
		cin>>a[i];
	}
	int target;
	cin>>target;
	int m= search(a,target);
	cout<<m<<endl;
	return 0;
}

三.总结

  • 二分法的两种形按照区间的范围操作
  • 循环条件与区间赋值的关系:
    循环条件控制区间的赋值边界,区间赋值决定循环能不能继续
算法学习来自b站:“代码随想录
例题来自704-二分查找-力扣

★,°:.☆( ̄▽ ̄)/$:.°★ 。结束🌼🌼🌼🌼🌼🌼

  • 32
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值