算法刷题Day1 | 704.二分查找、27.移除元素

目录

  • 0 引言
  • 1 二分查找
    • 1.1 我的解题
    • 1.2 修改后
    • 1.3 总结
  • 2 移除元素
    • 2.1 暴力求解
    • 2.2 双指针法(快慢指针)

请添加图片描述

  • 🙋‍♂️ 作者:海码007
  • 📜 专栏:算法专栏
  • 💥 标题:代码随想录算法训练营第一天 | 704.二分查找、27.移除元素
  • ❣️ 寄语:书到用时方恨少,事非经过不知难!

0 引言

1 二分查找

  • 🎈 文档讲解:https://programmercarl.com/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.html
  • 🎈 视频讲解:https://www.bilibili.com/video/BV1fA4y1o715/
  • 🎈 做题状态:有思路但是不清晰,对于循环的判断条件还有区间的变换存在疑惑(这些就是二分法的易错点)

1.1 我的解题

在这里插入图片描述

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

分析:没有标准答案简洁,原因是我的 leftright 赋值思路不对(相差1)。我是判断完大小后直接将 leftright 直接赋值 middle 。其实这样不对,因为 middle 的值已经判断过了,不需要再将这个索引值包含在 [left, right]区间中。

1.2 修改后

所以需要将代码进行如下修改,这样可以省去很多其他条件的判断。

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

1.3 总结

看到顺序排列的数组,就可以联想到二分法

二分法易错点:

  1. while循环条件:
    • while(left <= right)
    • while(left < right)
  2. left和right的赋值
    • left = middle+1; right = middle -1;
    • left = middle+1; right = middle;

其实while和left、right的赋值是对应的,

  • 使用while(left <= right)循环时,left = middle+1; right = middle -1;
  • 使用while(left < right)循环时,left = middle+1; right = middle;

因为当 left = middle+1; right = middle -1; left和right都把已经判断过的 middle 索引给排除在区间之外了,所以循环遍历的条件需要包括 left和right ,也就是 左闭右闭 区间。
left = middle+1; right = middle; 可以发现right没有把已经判断过的 middle 索引给排除在区间之外,所以循环条件不需要包括 right 的索引, 也就是 左闭右开 区间。


使用左闭右闭 区间时,最后left和right的结果是什么,当 left等于right的时候(此时middle也等于left和right),还会再执行一次循环,当nums[middle] > target 时 right = middle+1; 也就是说right又往右移动了一位。当nums[middle] <= target 时,right保持原位置不变。
这个特性可以帮助 35.搜索插入位置 这道题理解。

2 移除元素

  • 🎈 文档讲解:https://www.programmercarl.com/
  • 🎈 视频讲解:https://www.bilibili.com/video/BV12A4y1Z7LP/?vd_source=d499e7f3a8e68e2b173b1c6f068b2147
  • 🎈 做题状态:暴力求解没太大难度,快慢指针有需要理解的地方

2.1 暴力求解

一开始用暴力求解,输出答案不对,代码如下。我的的输出结果总是不能把最后一位元素给移除,后面发现遍历时没有遍历到最后一个元素。i < arraySize - 1 判断条件没写好,应该是 i < arraySize 或者 i <= arraySize - 1 。这个易错点以后要注意!!!

在这里插入图片描述


在这里插入图片描述

class Solution {
public:int removeElement(vector<int>& nums, int val) {int arraySize = nums.size();for (int i = 0; i <= arraySize - 1; i++){cout << "i = " << i << endl;if (nums[i] == val){for (int j = i; j < arraySize - 1; j++){nums[j] = nums[j + 1];}--arraySize;--i;}}return arraySize;}
};

2.2 双指针法(快慢指针)

快指针:遍历元素值
慢指针:存储新数组的元素值

思路:
遇到等于目标元素的值就跳过,遇到不等于目标元素的值就进行赋值。借助两个索引值(fastIndex和slowIndex)实现,fastIndex遇到目标元素就跳过,此时slowIndex不动,因为目标元素不需要存储。然后遇到不等于目标元素的值就进行赋值。此时是fastIndex在前面探路,然后slowIndex将fastIndex探路得到的结果进行保存。

因为数组的存放是顺序的,所以只有在遇到不等于目标元素的值时,slowIndex才会增加一,然后将非目标值保存下来。

fastIndex从头遍历到尾,所以直接用fastIndex作为遍历元素,条件为 fastIndex < nums.size() 即可。然后当 fastIndex 所指元素不等于目标元素值时,此时将 fastIndex 的值赋值给slowIndex 处。并且slowIndex加一。由此可知 nums 数组中有多少个不等于目标值的元素(个数就是slowIndex)。

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

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

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

相关文章

【MySQL】子查询优化、排序优化和覆盖索引

一、子查询优化 子查询可以通过一个SQL语句实现比较复杂的查询。但是子查询的效率不高。原因在于 执行子查询时&#xff0c;MySQL为内层查询语句的结果建立一个临时表&#xff0c;在查询结束后&#xff0c;会撤销这些临时表。这就导致消耗过多的CPU和IO资源&#xff0c;产生大…

AI 训练中 不收敛、欠拟合、过拟合、泛化能力是什么意思?

问题描述&#xff1a; AI 训练中 不收敛、欠拟合、过拟合、泛化能力是什么意思&#xff1f; 解答&#xff1a; 在人工智能&#xff08;AI&#xff09;训练过程中&#xff0c;你可能会遇到几个常见的问题&#xff0c;如不收敛、欠拟合、过拟合以及泛化能力的问题。这些问题通…

什么是攻防演练,能给企业带来什么

随着互联网技术的发展和企业信息化程度的提高&#xff0c;企业面临的网络安全威胁越来越多。为了保护企业的信息安全&#xff0c;攻防演练已经成为企业安全运营中不可或缺的一部分。攻击者通常会利用各种方法来破坏企业的安全系统和数据&#xff0c;因此企业需要像攻击者一样思…

C++ primer plus 学习 4.8 newdelete与存储空间

程序4.22 #include<iostream> #include<cstring> using namespace std;// 按照输入的字符串的长度来分配内存空间 char* getname(void){// 最大长度79char tmp[80]; // tmp自动存储&#xff0c;在栈中cout << "输入字符串: ";cin >> tmp;…

数据库自连接

力扣题目链接https://leetcode.cn/problems/employees-earning-more-than-their-managers https://leetcode.cn/problems/duplicate-emails/ 去重 select distinct… 数据库自连接通常在以下情况下需要使用&#xff1a; 层次关系查询&#xff1a;当表中的数据具有层次结构&…

Linux操作系统-05-文件查找与归档压缩

熟练使用find命令进行文件查找 熟练使用gerep命令对文件内容进行查找 熟练使用tar等命令进行文件归档与解压缩 一、文件查找 1、find命令 基本格式 &#xff1a;find 起始目录 查找类型 查找条件 #命令实例 find -name "hello.txt" #查找当前目…

灵活沟通,解决复杂功能需求与费用分歧

在软件开发领域&#xff0c;客户对于复杂功能的需求是司空见惯的事情。然而&#xff0c;当客户表达对此功能的渴望&#xff0c;却不愿支付相应费用时&#xff0c;良好的沟通就显得尤为关键。以下是一些建议&#xff0c;帮助你在这种情况下巧妙处理&#xff0c;达成双方满意的解…

QT 笔记 QGraphicsScene介绍

QT QGraphicsScene类介绍 分别介绍了以下内容&#xff1a; 类说明公共属性公共函数设置相关的函数槽函数信号量Event事件 1.类说明 QGraphicsScene是Qt中用于管理2D图形项&#xff08;QGraphicsItem&#xff09;的场景类。它充当了图形项的容器&#xff0c;负责管理图形项的…

HBuilder X删除之前登录的账号

打开目录 C:\Users\Administrator\AppData\Roaming\HBuilder X 用 HBuilder X 打开文件 prefs 将账号删除 保存文件 重启HBuilder X即可

JS删除数组中元素

在使用JavaScript进行项目开发的过程中&#xff0c;我们经常会有对list中的元素进行删除的需求&#xff0c;此时我们可以使用splice()方法来实现我们的需求。 一、splice方法的功能 splice()方法可以在list任何位置删除任意个元素。这个方法会改变原list 二、splice方法的语法…

获得月份天数

目录 【编程题】获得月份天数 -- 来自牛客网 方案一:if...else语句 方案二&#xff1a;数组&#xff08;最简单&#xff09; 方案三&#xff1a;switch语句 【编程题】获得月份天数 -- 来自牛客网 链接&#xff1a;【BC54】获得月份天数[牛客网] 题目要求:输入年份和月份&am…

7.3 支付模块 - 创建订单、查询订单、通知

支付模块 - 创建订单、查询订单、通知 文章目录 支付模块 - 创建订单、查询订单、通知一、生成支付二维码1.1 数据模型1.1.1 订单表1.1.2 订单明细表1.1.3 支付交易记录表 1.2 执行流程1.3 Dto1.3.1 AddOrderDto 商品订单1.3.2 PayRecordDto支付交易记录扩展字段1.3.3 雪花算法…

机器学习——感知机模型

机器学习系列文章 入门必读&#xff1a;机器学习介绍 文章目录 机器学习系列文章前言1. 感知机1.1 感知机定义1.2 感知机学习策略 2. 代码实现2.1 构建数据2.2 编写函数2.3 迭代 3. 总结 前言 大家好&#xff0c;大家好✨&#xff0c;这里是bio&#x1f996;。这次为大家带来…

C++的4种强制类型

C提供了4种强制类型转换的语法: 静态转换(static_cast) static_cast是用于在没有二义性的前提下进行基本数据类型转换的一种转换方式。它只能用于具有相关性的数据类型之间的转换,如将int类型转换为double类型。如果进行无关的数据类型之间的转换,编译器将报错。 用途:通常用…

描述下Vue自定义指令

描述下Vue自定义指令 &#xff08;1&#xff09;自定义指令基本内容&#xff08;2&#xff09;使用场景&#xff08;3&#xff09;使用案例 在 Vue2.0 中&#xff0c;代码复用和抽象的主要形式是组件。然而&#xff0c;有的情况下&#xff0c;你仍然需要对普通 DOM 元素进行底层…

基于springboot+vue的在线远程考试系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

亚马逊使用什么国外代理IP?跨境电商代理IP推荐

代理IP作为网络活动的有力工具&#xff0c;同时也是跨境电商的必备神器。亚马逊作为跨境电商的头部平台&#xff0c;吸引了大量的跨境电商玩家入驻&#xff0c;想要做好亚马逊&#xff0c;养号、测评都需要代理IP的帮助。那么应该使用什么代理IP呢&#xff1f;如何使用&#xf…

钡铼技术R40工业路由器稳定可靠支持环境检测应用

在现代工业化进程中&#xff0c;环境监测已经成为确保生产安全、提升环保效能的关键环节。而在这个领域中&#xff0c;钡铼技术的R40工业路由器以其卓越的稳定性和可靠性&#xff0c;在环境检测应用中发挥着至关重要的作用。 首先&#xff0c;钡铼技术R40工业路由器采用了先进…

url编码和json格式

pagination_str%7B%22offset%22%3A%22%7B%5C%22type%…440224%5C%22%2C%5C%22data%5C%22%3A%7B%7D%7D%22%7D 和 pagination_str: {"offset":"{\"type\":1,\"direction\":1,\"session_id\":\"1750756505440224\",\&qu…

水下蓝牙耳机有哪些?绝对物有所值的4大游泳耳机分享!

随着科技的不断进步&#xff0c;运动爱好者们对于耳机的需求也在不断提升。在众多运动场景中&#xff0c;游泳无疑是最为特别的一个。水下蓝牙耳机的出现&#xff0c;不仅解决了传统耳机无法防水的问题&#xff0c;更让游泳者可以在享受音乐的同时进行锻炼。然而&#xff0c;在…