「二分搜索Binary Search」

news2024/11/18 11:49:11

文章目录

  • 0 框架
  • 1 基本二分
    • 1.1 寻找一个数
      • 题解
      • Code
      • 结果
    • 1.2 寻找左侧边界的二分搜索
      • Code
    • 1.3 寻找右侧边界的二分搜索
      • Code

0 框架

int binarySearch(vector<int> &nums, int target)
{
	int left = 0, right = ....;//right具体看情况
	while (....)
	{
		int mid = left + (right - left) / 2;//防止溢出
		if (nums[mid] == target)
		{
			....
		}
		else if (nums[mid] < target)
		{
			left = ....
		}
		else if (nums[mid] <target)
		{
			right = ....
		}
	}
	return ....;
}

二分搜索其实也是双指针,左右指针。

1 基本二分

1.1 寻找一个数

在这里插入图片描述

题解

直接二分搜索解决。

Code

int binarySearch(vector<int> nums, int target)
{
	int left = 0;
	int right = nums.size() - 1;//注意
	while (left <= right)//注意
	{
		int mid = left + (right - left) / 2;
		if (nums[mid] == target)
		{
			return mid;
		}
		else if (nums[mid] < target)
			left = mid + 1;//注意
		else if (nums[mid] > target)
			right = mid - 1;//注意
	}
	return -1;
}

但是这个数有缺陷,假如有重复的数,例如[1,2,2,2,3],想要找左边界的2,应该返回索引为1,;或者右边界的2,返回索引3,但是发现找不了,只会给你返回中间的2,返回索引2,改进在下边。

结果

在这里插入图片描述

1.2 寻找左侧边界的二分搜索

Code

int left_bound(vector<int> nums, int target)
{
	if (nums.size() == 0) return -1;
	int left = 0;
	int right = nums.size();//注意,此处搜索区间其实是个左闭右开,因为nums.size()是越界了,索引的最后一个其实是要减去1的

	while (left < right)
	{
		int mid = left + (right - left) / 2;
		if (nums[mid] == target) right = mid;//搜索区间向左侧收缩,排除右边区间了,所以当发现nums[mid] == target的时候,不要直接返回,而是right = mid,再找左边界的,看左边界有没有值,实在不行,没找到,就返回mid了
		else if (nums[mid] < target) left = mid + 1;//左闭右开的区间,[mid + 1, right),排除mid这个点了,因为mid已经搜索过了
		else if (nums[mid] > target) right = mid;//因为是左闭右开的开区间,因为要排除mid,直接等于mid即可[left, mid),这样开区间就取不到mid了
	}
	if (left == nums.size()) return -1;
	return nums[left] == target ? left : -1;//返回left,right都可以
}

注意此处while符号变更了,改成小于号了<。那么为啥用<呢,因为首先搜索区间要包含数组的所有元素,其次,该怎么跳出while循环,当搜索区间没有元素的时候结束,那么搜索区间什么时候没有元素呢?当left = right的时候没有元素,所以这里是小于号<。

若要搜索区间变为左闭右闭的搜索区间,则稍微修改一下。

int left_bound(vector<int> nums, int target)
{
	int left = 0, right = nums.size() - 1;
	while (left <= right)
	{
		int  mid = left + (right - left) / 2;
		if (nums[mid] == target)
		{
			right = mid + 1;
		}
		else if (nums[mid] < target)
			left = mid + 1;//注意
		else if (nums[mid] > target)
			right = mid - 1;//注意
	}
	// 判断 target 是否存在于 nums 中
    // 此时 target 比所有数都大,返回 -1
    if (left == nums.length) return -1;
    // 判断一下 nums[left] 是不是 target
    return nums[left] == target ? left : -1;
}

1.3 寻找右侧边界的二分搜索

Code

int right_bound(vector<int> nums, int target) {
    int left = 0, right = nums.size(); //采用左闭右开表示
    
    while (left < right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] == target) {
            left = mid + 1; // 向右边进行收缩
        } else if (nums[mid] < target) {
            left = mid + 1;//左闭右开踢mid,左边[mid + 1, right)
        } else if (nums[mid] > target) {
            right = mid;//左闭右开踢mid,[left, mid)
        }
    }
    // 判断 target 是否存在于 nums 中
	// 此时 left - 1 索引越界
	if (left - 1 < 0) return -1;
	// 判断一下 nums[left] 是不是 target
	return nums[left - 1] == target ? (left - 1) : -1;// 因为最后left = mid + 1了,所以得减去1
}

改成左闭右闭的情况。

int right_bound(vector<int> nums, int target) {
    int left = 0, right = nums.size() - 1;
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] < target) {
            left = mid + 1;
        } else if (nums[mid] > target) {
            right = mid - 1;
        } else if (nums[mid] == target) {
            // 这里改成收缩左侧边界即可
            left = mid + 1;
        }
    }
    // 最后改成返回 left - 1
    if (left - 1 < 0) return -1;
    return nums[left - 1] == target ? (left - 1) : -1;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/799887.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ThinkPHP8知识详解:给PHP8和MySQL8添加到环境变量

在PHPenv安装的时候&#xff0c;环境变量默认的PHP版本是7.4的&#xff0c;MySQL的版本是5.7的&#xff0c;要想使用ThinkPHP8来开发&#xff0c;就必须修改环境变量&#xff0c;本文就详细讲解了如果修改PHP和MySQL的环境变量。 1、添加网站 启动phpenv&#xff0c;网站&…

抖音SEO源码开发指南:介绍如何开发抖音SEO源码的基本步骤和要点。

一、 抖音SEO源码开发指南&#xff1a; 确定目标&#xff1a;首先要明确开发抖音SEO源码的目标是什么&#xff0c;是提高搜索排名还是增加用户量等。根据不同的目标来制定开发策略和思路。 分析竞争&#xff1a;对于同类产品&#xff0c;要进行竞争分析&#xff0c;了解对手的…

安装Windows版nginx以及部署前端代码并就解决刷新出现404

文章目录 1.安装Nginx2.启动Nginx以及常用命令2.1 常用命令 3.部署前端打好的dist包4.前端部署nginx刷新后404&#xff0c;解决Nginx刷新页面后404的问题 1.安装Nginx &#xff08;1&#xff09;下载地址&#xff1a;https://nginx.org/en/download.html &#xff08;2&#x…

从0到1精通,Python接口自动化测试,测试进阶之道...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 如何实现python接…

【学习篇】学习Linux下常用的shell指令

前言&#xff1a;2020年写的一篇博文&#xff0c;Linux下好多指令都不太会用&#xff0c;想利用这个五一好好背一背&#xff0c;要不然用到的时候都反应不过来&#xff0c;还会用错&#xff0c;造成不可估量的风险&#xff0c;哭。。。 以下只摘录了我工作中经常要用到的一些指…

剑指offer10-I.斐波那契数列

学计算机的对这道题肯定不陌生&#xff0c;我记得是学C语言的时候学递归的时候有这道题&#xff0c;于是我就世界用递归写了如下代码&#xff1a; class Solution {public int fib(int n) {if(n1) return 1;if(n0) return 0;return (fib(n-1) fib(n-2)) % 1000000007;} } 到…

【Terraform学习】TerraformCloud入门介绍(快速入门)

TerraformCloud入门介绍 什么是 TerraformCloud&#xff1f; Terraform Cloud是Hashicorp Terraform的SaaS版本。 免费版功能 免费版功能包括版本控制集成、远程计划和实施远程计划和实施、通知及webhook、全http API驱动、状态管理、模拟计划、私有化模块注册器以及全HTTP界…

Nginx 高可用负载均衡(三种模式)

一、nginx普通集群负载均衡 1、安装keepalived (1)下载 https://www.keepalived.org/download.html(2)解压 tar -zxvf keepalived-2.0.18.tar.gz(3)使用configure命令配置安装目录与核心配置文件所在位置&#xff1a; ./configure --prefix/usr/local/keepalived --sysconf/e…

Java JVM虚拟机内部体系结构

JVM(Java虚拟机)是一个抽象机器。 它是一个提供可以执行Java字节码的运行时环境的规范。JVM可用于许多硬件和软件平台(即JVM是平台相关的)。 什么是JVM&#xff1f; JVM(Java虚拟机)是&#xff1a; 指定Java虚拟机的工作的规范。 但实现提供程序是独立的选择算法。 其实现是由…

25.5 matlab里面的10中优化方法介绍——牛顿法(matlab程序)

1.简述 1 牛顿法简介 牛顿迭代法&#xff08;Newton’s method&#xff09;又称为牛顿-拉夫逊&#xff08;拉弗森&#xff09;方法&#xff08;Newton-Raphson method&#xff09;&#xff0c;它是牛顿在17世纪提出的一种在实数域和复数域上近似求解方程的方法。 多数方程不存…

PHP登陆/php登录--【白嫖项目】

强撸项目系列总目录在000集 PHP要怎么学–【思维导图知识范围】 文章目录 本系列校训本项目使用技术 上效果图phpStudy 设置导数据库 项目目录如图&#xff1a;页面代码后台代码 这么丑的界面能忍&#xff1f;配套资源作业&#xff1a; 本系列校训 用免费公开视频&#xff0…

二叉树进阶(红黑树改造)

目录 引言 改造比较 1.颜色定义 2.节点构造 3.迭代器 3.1 迭代器的模板参数 3.2 迭代器的构造函数 3.3 迭代器的运算符重载函数 3.3.1 前置 3.3.2 前置-- 3.3.3 源码对比 3.3.4 其它运算符重载 4.红黑树改造 4.1 红黑树的begin(),end()函数 4.2 红黑树的模板…

又有一个手艺人震惊了B站用户

飞瓜数据&#xff08;B站版&#xff09;【热门视频榜】周榜显示&#xff0c;霸占全站视频流量第一的是来自UP主爱捣鼓的邢志磊发布的作品《我花了半年时间给猫做了个房子》。 视频在一周时间内新增播放1232.2万&#xff0c;新增点赞139.4万。 根据视频详细数据显示&#xff0c…

超详细推导逻辑回归公式与代码实现(二分类与多分类)

目录 概述逻辑回归理论数学推导二类分类多分类 代码实现备注 概述 本文使用梯度下降法对逻辑回归进行训练&#xff0c;使用类似于神经网络的方法进行前向传播与反向更新&#xff0c;使用数学公式详细推导前向传播与反向求导过程&#xff0c;包括二分类和多分类问题&#xff0c…

农业管理3d可视化管理大屏展示为乡村新基建加速

随着科技的不断发展&#xff0c;智慧农业已经成为当今社会农业发展的一个重要趋势。而数字孪生技术作为一种新兴的技术手段&#xff0c;正在逐渐应用到智慧农业领域中。 数字孪生公司深圳华锐视点基于数字孪生为核心技术打造的智慧大脑为乡村新基建加速&#xff0c;让乡村更“聪…

Python入门【推导式创建序列、字典推导式、集合推导式】(九)

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱敲代码的小王&#xff0c;CSDN博客博主,Python小白 &#x1f4d5;系列专栏&#xff1a;python入门到实战、Python爬虫开发、Python办公自动化、Python数据分析、Python前后端开发 &#x1f4e7;如果文章知识点有错误…

239.滑动窗口最大值

leetcode原题链接 题目描述&#xff1a; 给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 示例1: 输入&#xff1a;nums [1,…

【UniApp开发小程序】悬浮按钮+出售闲置商品+商品分类选择【基于若依管理系统开发】

文章目录 界面效果界面实现悬浮按钮实现商品分类选择界面使元素均匀分布 闲置商品描述信息填写界面价格校验 界面效果 【悬浮按钮】 【闲置商品描述信息填写界面】 【商品分类选择界面】 【分类选择完成】 界面实现 悬浮按钮实现 悬浮按钮漂浮于页面之上&#xff0c;等页面…

使用langchain与你自己的数据对话(三):检索(Retrieval)

之前我已经完成了使用langchain与你自己的数据对话的前两篇博客&#xff0c;还没有阅读这两篇博客的朋友可以先阅读一下&#xff1a; 使用langchain与你自己的数据对话(一)&#xff1a;文档加载与切割使用langchain与你自己的数据对话(二)&#xff1a;向量存储与嵌入 今天我们…

【C语言】文件操作(二)

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3; 目录 &#x1f4cc;补充1.sprintf2.…