【算法练习Day1】二分查找移除元素

在这里插入图片描述

​📝个人主页:@Sherry的成长之路
🏠学习社区:Sherry的成长之路(个人社区)
📖专栏链接:练题
🎯长路漫漫浩浩,万事皆有期待

文章目录

  • 二分查找
    • 解决方法一:左闭右开[left<=right),right = nums.size() - 1;
    • 解决方法二:左闭右闭(left<right),right = nums.size();
  • 移除元素
    • 暴力求解
    • 双指针遍历
    • 关于移除元素
  • 总结:

二分查找

704.二分查找

● 什么是区间不变量? 比如 区间取左闭右闭的话 那么每次区间二分 范围都是新区间的左闭右闭 后面做判断时 要一直基于这个左闭右闭的区间,其实区间定义成开或者闭都没有什么关系 只是要明确每次收缩范围后 范围内的元素是哪些 注意会不会漏掉边界

● 需要注意二分的几种情况
○ 当l = 0, r = n的时候因为r这个值我们在数组中无法取到,while(l < r) 是正确写法
○ 当l = 0, r = n - 1的时候因为r这个值我们在数组中可以取到,while(l <= r) 是正确写法
主要看能不能取到这个值

● 主要是对左闭右开[left<=right),左闭右闭(left<right)区别和怎么更新left,right的值有一定误解

由于数组元素为有序排列,我们仅需要确定搜索的左右边界。在该题中存在两种情况,即右边界的选择:

解决方法一:左闭右开[left<=right),right = nums.size() - 1;

在这种情况下,每次的搜索区间为 [left, right] 即左闭右闭区间,此时对应的循环条件应为 while (left <= right),终止条件为 left == right + 1,即 [right + 1, right],此时区间为空,故循环终止,程序返回 -1 即可;

class Solution {
public://这种情况是前闭后闭的情况int search(vector<int>& nums, int target) {int left=0;int right=nums.size()-1;while(left<=right){int mid=(left+right)/2;if(nums[mid]<target)left=mid+1;else if(nums[mid]>target)right=mid-1;else return mid;}return -1;}
};

由于mid被判断不是目的值,故两边界取的是mid的前一个值(改变右边界时)或mid的后一个值(改变左边界时),这样写的好处是把已经确定不在判断范围内的值给去掉,所以才写成从mid的前一个数或后一个数判断,而判断区间里由于两边区域都是闭区间所以可以带等于号。

易错:注意mid要放在while里面,mid本身是一直变化的

解决方法二:左闭右闭(left<right),right = nums.size();

对于这种情况,由于数组,此时的搜索区间为[left, right)即左闭右开区间,此时对应的循环条件为 while (left < right),终止条件为 left == right,即 [right, right],此时区间内仅存一个元素 right,直接返回 -1 是不对的,还需对该索引进行判断。

class Solution {
public://这种情况是前闭后开的情况int search(vector<int>& nums, int target) {int left=0;int right=nums.size();while(left<right){int mid=(left+right)/2;if(nums[mid]<target)left=mid+1;else if(nums[mid]>target)right=mid;else return mid;}return -1;}
};

第二种方法是左闭右开的情况,由于两侧边界不能相等,故判断区域不带等于号,右开:虽然右边界更改时,也不取mid值,但是由于右边区间是开区间,所以写成right=mid;是可行的,等于mid但是取不到

● 二分的最大优势是在于其时间复杂度是O(logn),因此看到有序数组都要第一时间反问自己是否可以使用二分。

● 其实二分还有很多应用场景,有着许多变体,比如说查找第一个大于target的元素或者第一个满足条件的元素,都是一样的,根据是否满足题目的条件来缩小答案所在的区间,这个就是二分的本质。

注意:二分的使用前提:有序数组

● 关于二分mid溢出问题:

  • mid = (l + r) / 2时,如果l + r 大于 INT_MAX(C++内,就是int整型的上限),那么就会产生溢出问题(int类型无法表示该数)

  • 所以写成 mid = l + (r - l) / 2或者 mid = l + ((r - l) >> 1) 可以避免溢出问题

● 对于二进制的正数来说,右移x位相当于除以2的x几次方,所以右移一位等于➗2,用位运算的好处是比直接相除的操作快

移除元素

27.移除元素

这道题主要是考察选手对于数组方面的掌握,

分两种方法 :一种是常见的暴力求解O(N*2),另一种则是稍微有些巧妙的双指针遍历O(N)

暴力求解

class Solution {
public:int removeElement(vector<int>& nums, int val) {int size=nums.size();for(int i=0;i<size;i++){if(nums[i]==val){for(int j=i+1;j<size;j++)nums[j-1]=nums[j];//避免溢出的处理方法size--;i--;}}return size;}
};

暴力求解主要是要注意size来记录返回数组的个数,每次找到val值后,i - -,这是因为找到val后val后的每个值都会向前一位,来挤掉之前的val值,让i - -,是从当前发现的val的下一个值来开始遍历,以免有落下的数没有判断。

双指针遍历

class Solution {
public:int removeElement(vector<int>& nums, int val) {int fast=0,slow=0;for(;fast<nums.size();fast++)if(nums[fast]!=val)nums[slow++]=nums[fast];return slow;}
};

slow、fast一开始都指向原点,然后fast向后走,直到找到val,开始做替换并且slow开始指向下一个位置,当fast走到最后,就说明所有的元素都被遍历完了,此时的slow值,就代表数组元素个数。

关于移除元素

● 快指针可以理解成在旧数组中找非目标元素,然后赋值给慢指针指向的新数组,虽然都指向一个数组

● 关于二分法和移除元素的共性思考
都是在不断缩小 left 和 right 之间的距离,每次需要判断的都是 left 和 right 之间的数是否满足特定条件。对于「移除元素」还可以理解为,拿 right 的元素也就是右边的元素,去填补 left 元素也就是左边的元素的坑,坑就是 left 从左到右遍历过程中遇到的需要删除的数,因为题目最后说超过数组长度的右边的数可以不用理,所以是以 left 为主,这样可能更直观一点。

● fast < nums.size() 和 fast <= nums.size()-1 没什么区别,那为什么第二个会在空数组时报数组越界的错误?
因为vector的size()函数返回值是无符号整数,空数组时返回了0,再减个1会溢出

总结:

今天的两道题其实在很久之前做过,但当时没有真正理解里面的细节问题,现在总算理解了。接下来,我们继续进行算法练习·。希望我的文章和讲解能对大家的学习提供一些帮助。

当然,本文仍有许多不足之处,欢迎各位小伙伴们随时私信交流、批评指正!我们下期见~

在这里插入图片描述

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

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

相关文章

ChatGPT WPS AI 一键核对两表数据差异

业务需求,找出两个表中不相同的内容。如下图: 像这样的表格中,要找出不同的值,手动核对效率不高。 现在我们有了ChatGPT,可以由人工智能来完成这一操作,高效,快速,准确定位差异值。 指令:请找出A1:G14 单元格区域和I1:O14单元格区域的不相同部分,将两部数据区域不相…

记一次hyperf框架封装swoole自定义进程

背景 公司准备引入swoole和rabbitmq来处理公司业务。因此&#xff0c;我引入hyperf框架&#xff0c;想用swoole的多进程来实现。 自定义启动服务封装 <?php /*** 进程启动服务【manager】*/ declare(strict_types1);namespace App\Command;use Swoole; use Swoole\Proce…

C语言每日一题(10):无人生还

文章主题&#xff1a;无人生还&#x1f525;所属专栏&#xff1a;C语言每日一题&#x1f4d7;作者简介&#xff1a;每天不定时更新C语言的小白一枚&#xff0c;记录分享自己每天的所思所想&#x1f604;&#x1f3b6;个人主页&#xff1a;[₽]的个人主页&#x1f3c4;&#x1f…

Weblogic反序列化漏洞(CVE-2018-2628/CVE-2023-21839复现)

内容目录 Weblogic反序列化漏洞(CVE-2018-2628/CVE-2023-21839)weblogic中间件CVE-2018-2628漏洞描述影响版本漏洞复现修复方案 CVE-2023-21839漏洞描述影响版本漏洞复现修复方案 Weblogic反序列化漏洞(CVE-2018-2628/CVE-2023-21839) weblogic中间件 WebLogic是美国Oracle公司…

在给应用ASO优化时要注意些什么

应用名称是搜索引擎优化和转化率优化非常重要的元素。用户在搜索结果页面中看到我们的应用程序&#xff0c;这是他们决定是否想要更多地了解我们应用的地方。当用户已经在查看产品页面时&#xff0c;应用程序名称也会影响转化率&#xff0c;如果列表元数据有吸引力&#xff0c;…

异步回调

Future 设计的初衷&#xff1a;对将来的某个事件的结果进行建模 package com.kuang.future;import com.kuang.pc.C;import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.uti…

静态路由与默认路由配置

实验原理&#xff1a; 路由分类 &#xff08;1&#xff09;根据目的网络的不同&#xff0c;路由可以划分为&#xff1a; 特定网络路由&#xff1a;目的网络为目的主机所在网络的IP地址&#xff0c;其子网掩码表示的前缀长度为32位&#xff08;对于IPv4地址&#xff09;&…

stm32_标准库_中断_按键点灯|蜂鸣器

配置流程 需要对AFIO、EXTI、NVIC、GPIOB进行配置形成通路将中断连接至CPU APB2总线连接的寄存器 LED灯代码 #include "stm32f10x.h" // Device header #include "Delay.h"GPIO_InitTypeDef GIPO_InitStruct;//结构体配置GPIO EXTI_InitTypeDef EXTI_…

WPS文件找回怎么做?文件恢复,4个方法!

“我平时习惯了用wps来记录一些工作心得或重点&#xff0c;不知道什么原因&#xff0c;有些很重要的文件莫名不见了&#xff0c;有什么方法可以帮我找回wps文件吗&#xff1f;” wps作一个常用的办公软件&#xff0c;有效的提高了我们的工作效率。在日常使用wps时&#xff0c;可…

非常详细的git-flow分支管理流程配置及使用

非常详细的git-flow分支管理流程配置及使用。 git-flow有两个涵义,一个是指软件开发领域的版本管理流程Gitflow。另一个是指git命令工具git flow。 目前业界主流的版本管理流程是Gitflow 和 trunk-based。 Gitflow流行的比较早。但是目前的流行度要低于 trunk-based模式工作…

MySQL8.0版安装教程 + Workbench可视化配置教程(史上最细、一步一图解)

文章目录 一、安装MySQL1、选择版本&#xff0c;点击“Download”进行下载2、双击下载好的安装包&#xff0c;点击运行3、选择安装类型为“Custom”4、依次进行选择&#xff0c;选到MySQL Servers 8.0.33 -X64&#xff0c;点击向右的箭头5、选中MySQL Servers 8.0.33 -X64&…

Mysql004:用户管理

前言&#xff1a;本章节讲解的是mysql中的用户管理&#xff0c;包括&#xff08;管理数据用户&#xff09;、&#xff08;控制数据库的访问权限&#xff09;。 目录 1. 查询用户 2. 创建用户 3. 修改用户密码 4. 删除用户 5. 权限控制 1. 查询用户 在mysql数据库中&#xff0…

古代有没有电子元器件?

手机&#xff0c;电脑&#xff0c;电视等等电子产品&#xff0c;无时无刻充斥在我们的生活中&#xff0c;如果有一天突然没有了这些功能多样的电子产品&#xff0c;估计大部分人都会一时之间难以适应。 这就好比正在上网&#xff0c;结果突然被人断了网&#xff0c;导致无网络连…

基于vue3 + ant-design 自定义SVG图标iconfont的解决方案;ant-design加载本地iconfont.js不显示图标问题

基于vue3 ant-design 自定义SVG图标iconfont的解决方案&#xff1b; ant-design加载本地iconfont.js不显示图标问题 一、准备工作 1、首先去阿里巴巴矢量图标库自定义添加自己的图标&#xff1b;网站地址https://www.iconfont.cn/ 整个步骤是&#xff1a;选择图标–添加到项…

变压器(电抗器) 红外测温作业指导书

1 范围 本标准化作业指导书规定了变压器(电抗器)红外测温(一般检测)工作的准备工作、测温流程图、 现场操作方法、测温周期和标准、测温记录管理等要求。 本标准化作业指导书适用于指导变压器(电抗器)红外测温的一般性检测工作。 2 规范性引用文件 下列文件对于本文件的应用…

积木报表 JimuReport v1.6.2-GA5版本发布—高危SQL漏洞安全加固版本

项目介绍 一款免费的数据可视化报表&#xff0c;含报表和大屏设计&#xff0c;像搭建积木一样在线设计报表&#xff01;功能涵盖&#xff0c;数据报表、打印设计、图表报表、大屏设计等&#xff01; Web 版报表设计器&#xff0c;类似于excel操作风格&#xff0c;通过拖拽完成报…

Linux复习-安装与熟悉环境(一)

这里写目录标题 虚拟机ubuntu系统配置镜像Linux命令vi编辑器3个模式光标命令vi模式切换命令vi拷贝与粘贴命令vi保存和退出命令vi的查找命令vi替换命令 末行模式复制、粘贴、剪切gcc编译器 虚拟机 VMware16 官网下载&#xff1a;vmware官网 网盘下载&#xff1a; 链接&#xff…

Pytorch 深度学习实践 day01(背景)

准备 线性代数&#xff0c;概率论与数理统计&#xff0c;Python理解随机变量和分布之间的关系 人类智能和人工智能 人类智能分为推理和预测 推理&#xff1a;通过外界信息的输入&#xff0c;来进行的推测 预测&#xff1a;例如&#xff0c;看到一个真实世界的实体&#xff…

idea更改java项目名

做了一个普通的java项目&#xff08;使用socket进行网络通信的练手项目&#xff09;&#xff0c;需要更改项目名&#xff0c;更改过程记录在这里。 修改项目名可能会出现很多错误&#xff0c;建议先备份当前项目 1.在idea里&#xff0c;右键项目名——》选择Refactor——》选择…