Day 1 二分算法(C++)

算法简介

二分查找(Binary Search)是一种常见的查找算法,它适用于已经排序好的数组或列表。它的基本思想是不断地将待查找区间分成两半,并通过比较目标值与中间元素的大小关系来确定目标值在哪一半中,从而缩小查找范围。这个过程一直重复,直到找到目标值或者确定目标值不存在为止。

基本条件:有序无重复

基本步骤:

  1. 初始化左右边界,通常为数组的起始和结束索引。
  2. 在循环中,计算中间位置索引,以及中间位置的值。
  3. 根据中间位置的值与目标值的大小关系,缩小搜索范围:
    • 如果中间值等于目标值,则找到了目标值,返回结果。
    • 如果中间值大于目标值,则说明目标值在左半部分,将搜索范围缩小为左半部分。
    • 如果中间值小于目标值,则说明目标值在右半部分,将搜索范围缩小为右半部分。
  4. 重复步骤 2 和步骤 3,直到找到目标值或者搜索范围为空。

常见的二分算法有两种写法:左闭右闭左闭右开

左闭右闭

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 {right = mid - 1; // 缩小搜索范围为左半部分}}return -1; // 搜索范围为空,未找到目标值
}
  • 时间复杂度:O(log n)
  • 空间复杂度:O(1)

左闭右开

最右边的不包含在内,所以注意三点

  • 循环条件:left == rifght无意义了
  • 初始化的时候right无需-1
  • 目标在在右边区间的时候,只需要更新right为middle就可以,因为本身就不包含
int binarySearch(vector<int>& nums, int target) {int left = 0;int right = nums.size(); // 定义target在左闭右开的区间里,即:[left, right)while (left < right) { // 因为left == right的时候,在[left, right)是无效的空间,所以使用 <int middle = left + ((right - left) >> 1);if (nums[middle] > target) {right = middle; // target 在左区间,在[left, middle)中} else if (nums[middle] < target) {left = middle + 1; // target 在右区间,在[middle + 1, right)中} else { // nums[middle] == targetreturn middle; // 数组中找到目标值,直接返回下标}}// 未找到目标值return -1;
}
  • 时间复杂度:O(log n)
  • 空间复杂度:O(1)

刷题

搜索插入位置

力扣题目链接
搜索插入位置
左闭右开
先贴代码

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

当循环结束时,说明目标值不存在于数组中,此时 left 表示目标值应该插入的位置。因为 left 表示第一个大于目标值的元素的索引,所以返回 left 即可。
我们对left进行更新的时候,都保证了更新后left左边的元素比目标值小,最后left == right,而right及其右边的元素肯定比目标值大
左闭右闭
先贴代码

class Solution {
public:int searchInsert(vector<int>& nums, int target) {int left = 0;int right = nums.size() - 1; // 初始化右边界为数组最后一个元素的索引while (left <= right) { // 使用左闭右闭的循环条件int middle = left + (right - left) / 2; // 计算中间位置的索引if (nums[middle] == target) {return middle; // 找到目标值,返回索引} else if (nums[middle] < target) {left = middle + 1; // 缩小搜索范围为右半部分} else {right = middle - 1; // 缩小搜索范围为左半部分}}return left; // 搜索范围为空,未找到目标值,返回插入位置}
};

在排序数组中查找元素的第一个和最后一个位置

力扣题目链接

在排序数组中查找元素的第一个和最后一个位置
先贴代码

class Solution {
public:vector<int> searchRange(vector<int>& nums, int target) {int lb = getLeftBorder(nums, target);int rb = getRightBorder(nums, target);if(lb == -1 || rb == -1){return {-1, -1};}else{return {lb, rb};}}int getLeftBorder(vector<int>& nums, int target) {int left = 0;int right = nums.size() - 1;int leftborder = -1;while(left <= right){int middle = (left + right) / 2;if(nums[middle] > target){right = middle - 1;}else if(nums[middle] < target){left = middle + 1;}else {right = middle - 1;leftborder = middle;}}return leftborder;}int getRightBorder(vector<int>& nums, int target) {int left = 0;int right = nums.size() - 1;int rightborder = -1;while(left <= right){int middle = (left + right) / 2;if(nums[middle] > target){right = middle - 1;}else if(nums[middle] < target){left = middle + 1;}else {left = middle + 1;rightborder = middle;}}return rightborder;}
};

这个题目对时间复杂度有要求,思考后发现可以使用两个二分查找的算法分别查找两个分别查找两个边界,我们只需要分析出来一个边界的函数就可以了
普通情况下我们正常处理,我们需要考虑的是nums[middle]==target,此时如果查找左边界,先标记一下,不然后面推出了通过left不好进行计算,我们更新right到middle前面

x 的平方根

力扣题目链接
x 的平方根

class Solution {
public:int mySqrt(int x) {if (x == 0 || x == 1) {return x;}int left = 1;int right = x;int ans = 0;while (left <= right) {int middle = left + (right - left) / 2;if (middle <= x / middle) { // 判断条件改为小于等于,避免溢出ans = middle;left = middle + 1;} else {right = middle - 1;}}return ans;}
};

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Uibot6.0 (RPA财务机器人师资培训第3天 )财务招聘信息抓取机器人案例实战

训练网站&#xff1a;泓江科技 (lessonplan.cn)https://laiye.lessonplan.cn/list/ec0f5080-e1de-11ee-a1d8-3f479df4d981https://laiye.lessonplan.cn/list/ec0f5080-e1de-11ee-a1d8-3f479df4d981https://laiye.lessonplan.cn/list/ec0f5080-e1de-11ee-a1d8-3f479df4d981(本博…

AGV|机器人导航识别二维码视觉传感器TDCS-0100与上位机PLC联机实例说明

目前二维码视觉导航的AGV出货量非常大&#xff0c;几乎都是仓储型AGV使用的导航方式。在地面或者天花板等位置标贴二维码作为标记点&#xff0c;通过扫描读取二维码信息和二维码相对相机的角度来确定当前位置。 本文重点介绍AGV|机器人导航识别二维码视觉传感器TDCS-0100与上位…

SCI一区 | Matlab实现WOA-TCN-BiGRU-Attention鲸鱼算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测

SCI一区 | Matlab实现WOA-TCN-BiGRU-Attention鲸鱼算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测 目录 SCI一区 | Matlab实现WOA-TCN-BiGRU-Attention鲸鱼算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测预测效果基本介绍模型描述程序…

使用Intellij idea编写Spark应用程序(Scala+SBT)

使用Intellij idea编写Spark应用程序(ScalaSBT) 对Scala代码进行打包编译时&#xff0c;可以采用Maven&#xff0c;也可以采用SBT&#xff0c;相对而言&#xff0c;业界更多使用SBT。 运行环境 Ubuntu 16.04 Spark 2.1.0 Intellij Idea (Version 2017.1) 安装Scala插件 安…

含“AI”量上涨,智能模组SC208系列助力智慧零售全场景高质发展

AI正重塑智慧零售产业&#xff0c;加速零售在采购、生产、供应链、销售、服务等方面改善运营效率和用户体验。零售行业经历了从线下到线上再到全渠道融合发展过程&#xff0c;“提质、降本、增效、高体验”是亘古不变的商业化与智能化方向。含“AI”量逐渐上涨的智慧零售正经历…

C语言例:n是否为素数(质数)

质数是指只能被1和自身整除的正整数。要判断一个数n是否为质数&#xff0c;可以通过以下步骤进行&#xff1a; 首先&#xff0c;判断n是否小于2&#xff0c;如果小于2&#xff0c;则不是质数。然后&#xff0c;从2开始&#xff0c;逐个判断n是否能被2到sqrt(n)之间的数整除。如…

数据可视化-ECharts Html项目实战(5)

在之前的文章中&#xff0c;我们学习了如何设置滚动图例&#xff0c;工具箱设置和插入图片。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢 数据可视化-ECharts…

增强现实(AR)在广告中的力量

The Power of AR in Advertising 写在前面 增强现实&#xff08;AR -Augmented Reality&#xff09;是指借助软件、应用程序和智能手机、平板电脑或耳机等设备&#xff0c;为日常生活添加视觉和音频元素的技术。如今&#xff0c;品牌和广告商可以在营销活动中使用AR&#xff0…

康奋威科技邀您到场参观2024长三角快递物流展

参展企业介绍 杭州康奋威科技股份有限公司创立于2005年&#xff0c;由国家“万人计划”专家任天挺先生创立并担任法人&#xff0c;是一家专业从事智能装备研发与制造的国家级高新技术企业。专注于自动化控制、机械设计、信息化方面的技术研究&#xff0c;主要为太阳能光伏、智…

【神经网络】得分函数,损失函数~

目录 引言 一、神经网络概述 1 定义 2 基本原理 二、得分函数 1 定义 2 应用方法 3 与神经网络 三、损失函数 1 定义 2实现方法 3 与神经网络 四、得分函数与损失函数的协同作用 1 关系 2 实际应用 六、代码事例 &#xfffc;、总结与展望 引言 在人工智能与机…

目标检测预测框可视化python代码实现--OpenCV

import numpy as np import cv2 import colorsys from PIL import Image, ImageDraw, ImageFontdef puttext_cn(img, text, pt, color(255,0,0), size16):if (isinstance(img, np.ndarray)): # 判断是否OpenCV图片类型img Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2…

(附源码)基于Spring Boot和Vue的智能订餐与外卖系统设计与实现

1. 引言 这部分通常包含了研究背景、研究意义、国内外研究现状、本文研究内容以及论文结构安排。 研究背景&#xff1a;介绍当前外卖市场的快速发展&#xff0c;以及智能订餐系统对改善人们生活的影响。研究意义&#xff1a;强调这类系统在现代生活中的作用和开发的创新点。国…