数组——LEETCODE的第35题(二分法与lower_bound函数)

数组——LEETCODE的第35题(二分法与lower_bound函数)

本文主要是根据leetcode 35题所写的关于数组的相关内容,主要包括:

  1. 数组的的特性
  2. leetcode第35题二分法的解题
  3. lower_bound函数的使用

文章目录

  • 数组——LEETCODE的第35题(二分法与lower_bound函数)
    • 一、数组
      • 1.1 注意事项
      • 1.2 数组的应用方法
    • 二、数组的二分法
      • 2.1 何为二分法
      • 2.2 二分法解题1
      • 2.3 lower_bound函数

一、数组

数组是一种数据结构,它可以存储一系列相同类型的元素,并通过索引来访问这些元素。在C++中,数组是一种非常基本且常用的数据类型,它具有以下特点:

  1. 相同类型的元素:数组中的元素必须是相同类型的。这意味着,如果你创建了一个整型数组,那么数组中的所有元素都必须是整数。

  2. 连续的内存空间:数组中的元素在内存中是连续存储的。这也意味着,数组的大小在创建时就已经确定,且不可变。

  3. 零基索引:在C++中,数组的索引是从零开始的。也就是说,第一个元素的索引是0,第二个是1,以此类推。

下面是一个简单的C++数组的声明和初始化示例:

#include <iostream>int main() {// 声明一个整型数组,大小为5int arr[5];// 初始化数组元素arr[0] = 10;arr[1] = 20;arr[2] = 30;arr[3] = 40;arr[4] = 50;// 访问数组元素并打印for (int i = 0; i < 5; ++i) {std::cout << "arr[" << i << "] = " << arr[i] << std::endl;}return 0;
}

1.1 注意事项

  1. 数组越界访问:在访问数组时一定要确保不要越界。如果访问了数组范围之外的元素,会导致未定义的行为,可能会导致程序崩溃或产生不可预测的结果。

  2. 数组大小:在声明数组时,必须指定数组的大小。这个大小在编译时必须是确定的,不能是变量或者动态分配的。如果需要动态大小的数组,应该使用动态分配的方式,比如使用std::vector

  3. 内存占用:数组在内存中是连续存储的,因此如果数组元素占用的内存空间很大,数组可能会占用大量的内存。这在处理大型数据集时需要特别注意。

1.2 数组的应用方法

  1. 遍历数组:使用循环结构,如forwhile循环,可以遍历数组中的所有元素。

  2. 数组作为函数参数:可以将数组作为函数的参数传递。在传递数组时,通常会传递数组的指针以及数组的大小,以便函数能够正确地处理数组。

  3. 多维数组:C++支持多维数组,比如二维数组、三维数组等。多维数组在处理矩阵、图像等问题时非常有用。

  4. 数组和指针的关系:在C++中,数组名本身就是数组的地址,因此可以将数组名作为指针使用。这意味着,可以通过指针操作数组的元素。

  5. 标准库中的数组类:除了原生的数组,C++标准库中也提供了std::array容器类,它提供了更多的功能和安全性,比如可以获取数组的大小、迭代器等。

  6. 算法与数组:C++标准库提供了丰富的算法,可以用于处理数组,如排序、查找、操作等。

综上所述,数组是C++编程中非常基础和常用的数据结构,熟练掌握数组的使用方法以及注意事项对于编写高效、安全的程序至关重要。

二、数组的二分法

35.搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

请必须使用时间复杂度为 O(log n) 的算法。
在这里插入图片描述

2.1 何为二分法

二分法(Binary Search)是一种在有序数组中查找特定元素的搜索算法。它的基本思想是每次将搜索区间减半,从而快速定位目标元素。

下面是二分法的基本步骤:

  1. 确定搜索区间:首先,确定整个有序数组作为搜索的初始区间。通常情况下,初始搜索区间是整个数组。

  2. 找到中间元素:计算搜索区间的中间位置,并将中间位置的元素与目标元素进行比较。

  3. 调整搜索区间:根据中间元素与目标元素的比较结果,调整搜索区间的范围。如果中间元素等于目标元素,搜索结束;如果中间元素大于目标元素,说明目标元素应该在中间元素的左侧,将搜索区间缩小为左半部分;如果中间元素小于目标元素,说明目标元素应该在中间元素的右侧,将搜索区间缩小为右半部分。

  4. 重复步骤2和3:根据目标元素与中间元素的比较结果,不断缩小搜索区间,直到找到目标元素或搜索区间为空。

下面是一个简单的示例代码,演示了如何使用二分法在有序数组中查找目标元素:

#include <iostream>
#include <vector>int binarySearch(const std::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 -1; // 目标元素不存在,返回 -1
}int main() {std::vector<int> nums = {1, 3, 5, 7, 9, 11, 13};int target = 7;int result = binarySearch(nums, target);if (result != -1) {std::cout << "Target found at index " << result << std::endl;} else {std::cout << "Target not found" << std::endl;}return 0;
}

在这个示例中,我们定义了一个 binarySearch 函数来执行二分查找。首先,我们将整个有序数组作为初始搜索区间。然后,通过不断调整搜索区间的范围,最终找到目标元素的索引位置或者确定目标元素不存在。

2.2 二分法解题1

对于力扣35题,可以使用简单的二分法进行解题,

class Solution {
public:int searchInsert(vector<int>& nums, int target) {int front = 0;int rear = nums.size() - 1; // 使用nums.size()获取vector中的元素个数while (front <= rear) {int middle = front + ((rear - front) >> 1);if (nums[middle] > target) {rear = middle - 1;} else if (nums[middle] < target) {front = middle + 1;} else {return middle;}}return front; // 返回插入位置}
};

很简答的一个解法,但是还有一个C++的库可以提供更简单的使用方法

2.3 lower_bound函数

return lower_bound(nums.begin(),nums.end(),target) - nums.begin();

std::lower_bound 函数是 C++ 标准库 <algorithm> 头文件中的一个函数,用于在已排序的序列中查找第一个不小于给定值的元素。它返回一个迭代器,指向第一个不小于目标值的元素。


std::lower_bound 函数的声明如下:

template< class ForwardIt, class T >
ForwardIt lower_bound(ForwardIt first, ForwardIt last, const T& value);

这个函数用于在有序序列中查找第一个不小于给定值的元素,并返回指向该元素的迭代器。以下是函数的参数解析:

  • first:表示搜索范围的起始位置的迭代器。
  • last:表示搜索范围的结束位置的迭代器。注意,该位置不包含在搜索范围内。
  • value:表示要查找的目标值。

函数将返回一个迭代器,指向序列中第一个不小于目标值的元素,或者如果所有元素都小于目标值,则返回 last


在代码中,lower_bound(nums.begin(), nums.end(), target) 返回一个迭代器,指向 nums 中第一个不小于 target 的元素。然后,通过减去 nums.begin(),我们得到了这个迭代器相对于 nums.begin() 的偏移量,也就是元素的索引位置。

需要注意的是,如果目标值存在于序列中,lower_bound 返回的是第一个不小于目标值的元素的迭代器,而不是目标值本身的迭代器。因此,如果要返回目标值在序列中的确切位置,还需要对返回的迭代器进行进一步的判断。

以下是一个示例代码:

#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> nums = {1, 3, 5, 7, 9};int target = 6;int insertPosition = std::lower_bound(nums.begin(), nums.end(), target) - nums.begin();std::cout << "Insert position for " << target << " is: " << insertPosition << std::endl;return 0;
}

输出将会是:Insert position for 6 is: 3

这表明对于值为6的元素,应该插入到索引位置3的位置上,也就是在元素7之前。

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

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

相关文章

面试题(一)

目录 1.JDK、JRE、JVM之间的区别 2.hashcode()和equals()的区别 3.String、StringBuffer、StringBuilder的区别 4.泛型中extends和super的区别 5.和equals()的区别 6.重写和重载的区别 7.List和Set的区别 8.ArrayList和LinkedList区别 9.谈谈ConcurrentHashMap的原理 …

LangChain核心模块 Retrieval——文档加载器

Retrieval ​ 许多LLM申请需要用户的特定数据&#xff0c;这些数据不属于模型训练集的一部分&#xff0c;实现这一目标的主要方法是RAG(检索增强生成)&#xff0c;在这个过程中&#xff0c;将检索外部数据&#xff0c;然后在执行生成步骤时将其传递给LLM。 ​ LangChain 提供…

Unsafe的CAS操作及线程park与unpark

如下是一个参照AQS进行的一个加锁及解锁的简单实现&#xff1a; 多线程并发进行同步业务操作&#xff1b;加锁&#xff1a;尝试进行cas 0->1操作&#xff1b;如果加锁成功则进行业务处理&#xff0c;然后进行锁释放 1->0&#xff0c;然后将列头的线程进行唤醒&#xff1…

GDAL中的地理坐标系、投影坐标系及其相互转换

目录 地理坐标系 国内常用地理坐标系 投影坐标系 国内常用投影坐标系&#xff08;不推荐使用&#xff09; 坐标转换 地理坐标转为投影坐标 投影坐标转为地理坐标 地理坐标系 原理参考这篇文章&#xff1a;地理坐标系与投影坐标系区别与联系 https://yunxingluoyun.blog.…

webserver如何从零开始?

我们要做一个项目&#xff0c;过程是怎么样的呢&#xff1f;git clone ...部署&#xff0c;测试&#xff0c;然后开始写么&#xff0c;这样你大概率会“猪脑过载”&#xff0c;对一个项目的每个部分都没有清晰认识&#xff0c;能写出什么来&#xff1f;写之前当然需要测试每个功…

Linux网络协议栈从应用层到内核层③

文章目录 1、write源码剖析2、vfs层进行数据传输3、socket层进行数据传输4、tcp层进行数据传输5、ip层进行数据传输6、网络设备层进行数据传输7、网卡驱动层进行数据传输8、数据传输的整个流程 1、write源码剖析 系统调用原型 ssize_t write(int fildes, const void *buf, si…

Linux 在线yum安装: PostgreSQL 15.6数据库

Linux 在线yum安装&#xff1a; PostgreSQL 15.6数据库 1、PostgreSQL数据库简介2、在线安装PostgreSQL15.63、配置 PostgreSQL的环境变量4、使用默认用户登录PostgreSQL5、配置 PostgreSQL 允许远程登录6、修改 PostgreSQL 默认端口7、创建数据库和表、远程用户zyl8、pgAdmin远…

MATLAB环境下基于离散小波变换和主成分平均的医学图像融合方法

随着计算机技术和生物影像工程的日趋成熟&#xff0c;医学图像为医疗诊断提供的信息越来越丰富。目前&#xff0c;由于医学成像的设备种类繁多&#xff0c;导致医生获得的图像信息差异较大。如何把这些信息进行整合供医生使用成为当务之急。基于此&#xff0c;医学图像融合技术…

Rust 实战练习 - 8. 内存,ASM,外挂 【重磅】

目标&#xff1a; C写一个Demo版本的游戏由浅入深&#xff0c;了解外挂原理Linux/Android下实现内存读取ptrace实现内存修改&#xff08;依赖第三方库&#xff09; 先准备一个C写的小游戏 #include <stdio.h> #include <string.h>struct Role {float pos_x; // …

vue3+vite配置环境变量

1、创建环境变量文件&#xff1a;首先在vue3项目根目录创建.env.development 和 .env.prodution两个文件&#xff0c;分别为开发和生产环境&#xff08;必须.env.开头&#xff0c;需要额外环境&#xff0c;配置自定义的文件名称即可&#xff09; 2、在环境变量文件分别写对应…

Android内存优化项目经验分享 兼顾效率与性能

背景 项目上线一段时间后,回顾重要页面 保证更好用户体验及生产效率&#xff0c;做了内存优化和下载导出优化&#xff0c;具体效果如最后的一节的表格所示。 下面针对拍摄流程的两个页面 预览页 导出页优化实例进行介绍&#xff1a; 一.拍摄前预览页面优化 预览效果问题 存在…

试试前端自动化测试(基础篇)

众所周知的原因&#xff0c;前端作为一种特殊的 GUI 软件&#xff0c;做自动化测试困难重重。在快速迭代&#xff0c;UI 变动大的业务中&#xff0c;自动化测试想要落地更是男上加男 &#x1f436;。 近期的学习过程中&#xff0c;翻阅了众多前端自动化测试相关的文章&#xf…

【兆易创新GD32H759I-EVAL开发板】 关于LVGL 的内存配置

【兆易创新GD32H759I-EVAL开发板】拥有外部32MB的 SDRAM 在使用LVGL时 可以随意分配大小 但是我们也应该明白 所定义的内存大小的 的一些概念 LVGL中 有单独的 定义 LV_MEM_SIZE 定义内存大小 LVLG 中 在定义 显示程序 接口时 还需要用到 lv_disp_draw_buf_init() 分配显存…

MyBatis框架解析与优化

MyBatis 是一个半 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;它内部封装了 JDBC&#xff0c;开发时只需要关注 SQL 语句本身&#xff0c;不需要花费精力去处理加载驱动、创建连接、创建 statement 等繁杂的过程。 什么是 MyBatis&#xff1f; MyBatis 是一个半…

【3D reconstruction 学习笔记】

三维重建 3D reconstruction 1. 相机几何针孔相机摄像机几何 2. 相机标定线性方程组的解齐次线性方程组的解非线性方程组的最小二乘解透镜相机标定带畸变的相机标定 3. 单视图重建2D平面上的变换3D空间上的变换单视测量无穷远点 无穷远线 无穷远平面影消点 影消线单视重构 4. 三…

天艺制盖邀您参观2024第七届世界燕窝及天然滋补品博览会

2024第七届世界燕窝及天然滋补品博览会 2024年8月7-9日| 上海新国际博览中心 上海燕博会 世界燕窝及天然滋补品展览会暨世界滋补产业生态发展大会&#xff08;简称上海燕博会&#xff09;&#xff0c;2017年创办于中国上海&#xff0c;是一年一度的世界燕窝滋补品行业盛会。…

宁波中墙建材施工过程中,如何确保陶粒复合砌块的垂直度和水平度符合要求?

宁波中墙建材陶粒复合砌块如何使用 确保陶粒复合砌块施工质量的建议&#xff1a; 基层处理&#xff1a;在施工前&#xff0c;确保基层干净、平整、坚固&#xff0c;去除表面的杂物和油污等。 砌块质量&#xff1a;选择质量好、尺寸规格一致的陶粒复合砌块&#xff0c;避免使用有…

【串口开发】android 智能设备开发 知识笔记

1.一般的波特率选择115200,自己玩的可以用9600等随便的 2.为了android方便操作,引入了 implementation com.licheedev:android-serialport:2.1.3包。 不然就得手写了,比如像这样 ,打开串口监听 // 打开串口boolean openSerialPort = mSerialPortManager.setOnOpenSerial…

每天一个数据分析题(二百二十八)

在超参数调参的各种方法中&#xff0c;贝叶斯优化搜索(Bayesian Optimization)是一种非常有效的方法。请问在贝叶斯搜索中&#xff0c;用于估计目标函数并为下一次迭代提供建议的模型是什么&#xff1f; A. 线性回归 B. 随机森林 C. 高斯过程 D. 神经网络 题目来源于CDA模…

vue js有哪些优点和缺点

Vue.js 是一个流行的前端 JavaScript 框架&#xff0c;用于构建用户界面和单页面应用。以下是 Vue.js 的一些主要优点和缺点&#xff1a; 优点&#xff1a; 轻量级和简洁&#xff1a;Vue.js 的核心库专注于视图层&#xff0c;并且非常轻量&#xff0c;这使得它可以很容易地与其…