移动零+复写零+快乐数+盛最多水的容器+有效三角形的个数
前言
2025.3.31,今天开始每日五道算法题,今天的算法题如标题!
双指针算法
在做今天的算法题之前,先来介绍一下今天会用到的算法!
双指针算法分为了两种常见的形式:对撞指针和快慢指针!
对撞指针,顾名思义就是会碰撞到一起去,那么这两个指针就会形成一左一右向中间移动!
一般来说,对撞指针的结束条件有两种:
两个指针在同一个位置!即 left == right;
两个指针交错!即 left > right;
快慢指针,也叫龟兔赛跑算法,基本思想为两个不同速度的指针在数组或链表等序列结构上移动。
我们常见的就是环状结构就会用到我们的快慢指针!
那么介绍完今天的算法,那么就直接到我们的题目当中吧!
移动零
传送门如下:
283. 移动零 - 力扣(LeetCode)
先来看一下题目

题目解析
我们先来看一下结果,我们可以看到明显分为了两个区块,左区块都是非0的数,右区块都是0的数。那么我们就定义[0,slow]为非0的区块,[slow+1,num.size()-1]为0的区块。
可以看到!只需要保持两个指针分割这两个区间即可!也就是[0,slow]和[slow+1,fast-1],至于[fast,num.size()-1]这个待处理区间,我们暂时不考虑。
那么我们就可以定义两个指针的作用
fast指针:用于遍历整个数组。
slow指针:用于分割非0和0区块,指向的是最后一个非0元素!
那么我们来考虑fast指针和slow指针初始化的值!
由于我们是不知道一开始非0元素是在哪个位置,所以我们将slow指针设置为-1,由于我们的fast指针是用于遍历整个数组的,所以我们设置为0即可!
那么我们继续来考虑两个指针移动的规则!
我们以fast指针作为参考!也就是两种情况!
1.遇到的元素为0,我们只需要将fast指针继续++即可。
因为我们的目标是[slow+1,fast-1]的区间为0区块,我们的slow是不需要往前走的,fast向前走一步是能够包裹住这个遇到的元素为0的块的!
2.遇到的元素为非0,我们就需要将fast当前位置的元素和slow当前位置+1的元素进行互换,并且两个指针都++
因为[slow+1,fast-1]都是0,遇到的fast为非0,互换之后slow+1就是非0,fast就是0,那么两个指针++之后,也是符合[slow+1,fast-1]为0区间,而且[0,slow]为非0区间。
那么这里我们就把情况考虑完成!那么我们什么时候停止移动?
当然是我们的fast指针到了我们数组的尾部啦!
那么我们再来考虑一个特殊情况!
当我们的数组只有一个元素,非0或0是否满足以上我们分析的过程?
1.当这个元素是0,我们fast直接跑出去了,就不需要循环了。满足!
2.当这个元素不是0,我们的fast也就是0号位元素和slow+1也就是0号位元素进行交换。满足!
代码编写
所以理论成立!我们直接开始代码的编写!
class Solution {
public:void moveZeroes(vector<int>& nums) {for(int fast = 0, slow = -1; fast < nums.size(); fast++){if(nums[fast]){swap(nums[++slow], nums[fast]);}}}
};
提交我们的结果!

那么这一题我们就完成啦!
复写零
传送门如下:
1089. 复写零 - 力扣(LeetCode)
先来看一下题目!

题目解析
我们看到这个题,需要进行原地修改,所以我们不可能去考虑从左到右去进行复写!
为什么呢?因为我们复写的时候会覆盖掉我们后面的元素。所以我们就要从右往左进行覆写!这样我们就不会覆盖掉前面的元素!
之后我们发现,我们只知道要覆盖最后一个元素开始,但是不知道是哪个元素覆盖过来,所以我们就要先找到第一个要覆写的元素。
那么我们就需要使用到快慢指针去找到我们的第一个要覆写操作的元素!
我们先考虑边界情况,因为我们后续找到了第一个要覆写的元素的位置,我们的快指针也会达到边界的位置,我们移动两步的这个操作很有可能会越界,所以我们需要考虑边界问题!毕竟我们要重复利用这两个指针的嘛!
这里也不是很难哦,只需要考虑我们的快指针刚好等于数组大小即可!
我们只需要将整个数组的最后一个元素设置为0,之后我们的快指针-2,慢指针-1即可。
为什么呢?如果我们会越界,那么只有一种情况,就是我们遇到了0,我们移动了两次,那么数组只剩一个位置了,那么这个位置只能是0,我们就需要设置最后一个位置为0,而且快指针移动了两次,我们就在数组最后的那个位置的后一位,由于我们不需要操作最后一位,所以我们就需要回退两位,到数组的最后一位进行操作,那么最后一位已经操作,那么我们的慢指针现在所在位置就是已经操作过的位置,那么我们的慢指针也需要回退一位。
那么考虑了我们的边界问题,我们就来考虑找第一个需要覆写的位置。
我们要考虑的就是快慢指针进行移动的规则!
1.慢指针遇到非0元素,我们两个指针都移动一个单位即可
2.慢指针遇到0元素,我们的慢指针移动一位,快指针移动两位即可!
那么考虑完找到第一个覆写位置,我们就要考虑怎么样覆写
1.slow指针位置元素为0,fast-1和fast位置都改为0,slow-=1,fast-=2
2.slow指针位置元素为非0,fast位置改为slow指针位置元素,slow-=1,fast-=1
代码编写
理论成立,我们赶快进行代码的编写!
class Solution {
public:void duplicateZeros(vector<int>& arr) {int fast = -1,slow = 0;int sz = arr.size();// 1. 先找到最后一个数while(fast < sz){if(arr[slow])fast++;elsefast += 2;if(fast >= sz-1)break;slow++;}// 2. 处理边界情况if(fast == sz){arr[sz-1] = 0;fast -= 2;slow--;}// 3. 从后向前完成复写while(slow >= 0){if(arr[slow])arr[fast--] = arr[slow--];else{arr[fast--] = 0;arr[fast--] = 0;slow--;}}}
};
看一下提交结果

快乐数
传送门如下:
202. 快乐数 - 力扣(LeetCode)
我们还是先来看一下题目

题目解析
我们一眼就看到了这个无限循环这四个字,说明什么?
我们要用快慢指针去找循环圈子!快指针移动两步,慢指针移动一步,当两个指针重合时候就可以说明我们的这个数是否为快乐数!其实就是判断链表是否有环的题!
但是,我们发现,其实一堆1其实也是可以组成一个为1的环,只不过是在自己身上转而已。
所以我们考虑的就是当这个快慢指针的值重合的时候是否为1即可!
这里我们其实就已经把题目做出来了,那么直接就到我们的代码编写!
代码编写
class Solution {
public:int bitSum(int num){int sum = 0;while(num){int b = num % 10;sum+= b*b;num = num / 10;}return sum;}bool isHappy(int n) {int slow = n;int fast = bitSum(n);while(slow != fast){slow = bitSum(slow);fast = bitSum(bitSum(fast));}if(slow == 1) return true;return false;}
};
看一下提交结果!

盛最多水的容器
传送门如下:
11. 盛最多水的容器 - 力扣(LeetCode)
先来看一下题目

题目解析
我们这道题其实就是计算体积,木桶效应,最短的那个作为高,这个体积就是长*高
当然这道题我们不打算使用暴力枚举!所以我们就要用对撞指针来使得整个计算体积的长最大!
我们举个例子来模拟一下!
[1,8,6,2,5,4,8,3,7]
我们可以看到数组的0号位和数组的8号位也就是最后一位!此时体积为(8-0)* 1 = 8
如果我们使用1和3进行计算,高度肯定不变,但是长减少了,所以我们就不需要考虑了,我们就直接开始考虑左边的8和7进行考虑。
同理应该去掉3,所以我们只需要对撞指针选择最大的元素留下,最小的元素剔除,之后计算出当前最大的体积即可!之后比较当前最大体积就可以算出最大体积了!
那么为什么我们要剔除较小的元素?
因为我们剔除一个元素,宽度一定会减少,但是我们要尽可能让高度变大!
那么还有一个问题,遇到两个相同大小的元素时应该如何抉择?
其实都一样!你就算移动那个旁边是一个很大的数的指针,这高度还是原来的那个元素,但是我们的宽度还是减小的,所以相同大小的元素不需要考虑特殊情况,只需要按照你的习惯去移动就行。
代码编写
那么直接到代码编写!
class Solution {
public:int maxArea(vector<int>& height) {int left = 0;int right = height.size()-1;int ret = 0;while(left < right){int v = min(height[left], height[right]) * (right - left);ret = max(ret, v);if(height[left] < height[right]){left++;}else{right--;}}return ret;}
};
来看一下结果!

有效三角形的个数
传送门:
611. 有效三角形的个数 - 力扣(LeetCode)
我们先来看一下题目

题目解析
首先不是侮辱大家!我们先来看一下是否为三角形的定理!
a + b > c
a + c > b
b + c > a
这个看起来就很乱,需要证明三个条件,但是如果我们知道a <= b <= c,就只需要证明一个条件即可!毕竟c大于等于任何一条边
所以这道题我们就需要先排序!
那么排完序,我们来举个例子!
假如有一个数组为[1, 2, 2, 3,5,9,11]
我们先固定最大值11
我们再用碰撞指针!找到了1和9小于11,由于单调性,只能移动我们的左指针,找到了3,可以看到3 + 9 > 11,那么继续移动左指针还会变大,所以能够组成三角形的就只有[3,9,11]和[5,9,11]两组,其实就是9的数组坐标-3的数组坐标,也就是右指针-右指针的值。此时就可以移动右指针了,3 + 5 < 11,左指针右移,碰撞了,所以就结束了这一轮,那么就完成了和固定值11的三角形边配对了。
那么固定值9同理。
总结规律:
已知 a <= b <=c
a + b > c 得 ret = right - left 且 right--
a + b <= c 得 left++
代码编写
理论成立,代码编写!
class Solution {
public:int triangleNumber(vector<int>& nums) {sort(nums.begin(), nums.end());int sz = nums.size();int ret = 0;//遍历固定最大值for(int i = sz -1; i>=2; i--){int left = 0;int right = i - 1;while(left < right){if(nums[left] + nums[right] > nums[i]){ret += right - left;right--;}else{left++;}}}return ret;}
};
我们来看一眼运行结果

那么今天的五道算法题就到此为止,我们期待下一期!
相关文章:
移动零+复写零+快乐数+盛最多水的容器+有效三角形的个数
前言 2025.3.31,今天开始每日五道算法题,今天的算法题如标题! 双指针算法 在做今天的算法题之前,先来介绍一下今天会用到的算法! 双指针算法分为了两种常见的形式:对撞指针和快慢指针! 对撞…...
Linux中常用的文件管理命令
一、文件和目录的建立 文件 touch命令 单一文件的创建 当按下回车后我们就可以在桌面获得一个名字叫file的文件 [rootlocalhost Desktop]# touch file 同步文件访问时间和文件修改时间 由上两图可知touch file这个命令还可以把文件访问时间和文件修改时间变成touch file命…...
Root Cause Analysis in Microservice Using Neural Granger Causal Discovery
Root Cause Analysis in Microservice Using Neural Granger Causal Discovery 出处:AAAI 24 摘要 近年来,微服务因其可扩展性、可维护性和灵活性而在 IT 运营中得到广泛采用。然而,由于微服务中的复杂关系,当面临系统故障时,站点可靠性工程师 (SRE) 很难查明根本原…...
学习笔记—数据结构—二叉树(链式)
目录 二叉树(链式) 概念 结构 初始化 遍历 前序遍历 中序遍历 后序遍历 层序遍历 结点个数 叶子结点个数 第k层结点个数 深度/高度 查找值为x的结点 销毁 判断是否为完整二叉树 总结 头文件Tree.h Tree.c 测试文件test.c 补充文件Qu…...
微前端 - 以无界为例
一、微前端核心概念 微前端是一种将单体前端应用拆分为多个独立子应用的架构模式,每个子应用可独立开发、部署和运行,具备以下特点: 技术栈无关性:允许主应用和子应用使用不同框架(如 React Vue)。独立部…...
DIskgenius使用说明
文章目录 一、概述1. 软件简介2. 系统要求 二、核心功能1. 分区管理(1) 查看磁盘分区(2) 创建与删除分区(3) 调整分区大小(4) 格式化分区 2. 数据恢复(1) 恢复已删除文件(2) 恢复丢失分区(3) 恢复误格式化分区 3. 磁盘复制(1) 克隆磁盘(2) 磁盘镜像 4. 文件操作(1) 文件复制与移…...
深入理解指针5
sizeof和strlen的对比 sizeof的功能 **sizeof是**** 操作符****,用来**** 计算****变量或类型或数组所占**** 内存空间大小****,**** 单位是字节,****他不管内存里是什么数据** int main() {printf("%zd\n", sizeof(char));p…...
一文详解QT环境搭建:Windows使用CLion配置QT开发环境
在当今的软件开发领域,跨平台应用的需求日益增长,Qt作为一款流行的C图形用户界面库,因其强大的功能和易用性而备受开发者青睐。与此同时,CLion作为一款专为C/C打造的强大IDE,提供了丰富的特性和高效的编码体验。本文将…...
NE 综合实验3:基于 IP 配置、链路聚合、VLAN 管理、路由协议及安全认证的企业网络互联与外网访问技术实现(H3C)
综合实验3 实验拓扑 设备名称接口IP地址R1Ser_1/0与Ser_2/0做捆绑MP202.100.1.1/24G0/0202.100.2.1/24R2Ser_1/0与Ser_2/0做捆绑MP202.100.1.2/24G0/0172.16.2.1/24G0/1172.16.1.1/24G0/2172.16.5.1/24R3G5/0202.100.2.2/24G0/0172.16.2.2/24G0/1172.16.3.1/24G0/2172.16.7.1/…...
Ground Truth(真实标注数据):机器学习中的“真相”基准
Ground Truth:机器学习中的“真相”基准 文章目录 Ground Truth:机器学习中的“真相”基准引言什么是Ground Truth?Ground Truth的重要性1. 模型训练的基础2. 模型评估的标准3. 模型改进的指导 获取Ground Truth的方法1. 人工标注2. 众包标注…...
双重token自动续期解决方案
Token自动续期实现方案详解 Token自动续期是提升用户体验和保障系统安全的关键机制,其核心在于无感刷新和安全可控。以下从原理、实现方案、安全措施和最佳实践四个维度展开说明: 一、核心原理:双Token机制 Token自动续期通常采用 Access …...
我与数学建模之启程
下面的时间线就是从我的大二上开始 9月开学就迎来了本科阶段最重要的数学建模竞赛——国赛,这个比赛一般是在9月的第二周开始。 2021年国赛是我第一次参加国赛,在报名前我还在纠结队友,后来经学长推荐找了另外两个学长。其实第一次国赛没啥…...
多段圆弧拟合离散点实现切线连续
使用多段圆弧来拟合一个由离散点组成的曲线,并且保证切线连续。也就是说,生成的每一段圆弧之间在连接点处必须有一阶导数连续,也就是切线方向相同。 点集分割 确保每个段的终点是下一段的起点,相邻段共享连接点,避免连接点位于数…...
烧结银:解锁金刚石超强散热潜力
烧结银:解锁金刚石超强散热潜力 在材料科学与热管理领域,金刚石凭借超高的热导率,被誉为 “散热之王”,然而,受限于其特殊的性质,金刚石在实际应用中难以充分发挥散热优势。而烧结银AS9335的出现&#x…...
【蓝桥杯】第十四届C++B组省赛
⭐️个人主页:小羊 ⭐️所属专栏:蓝桥杯 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 试题A:日期统计试题B:01串的熵试题C:冶炼金属试题D:飞机降落试题E:接…...
企业级海外网络专线行业应用案例及服务商推荐
在全球化业务快速发展的今天,传统网络技术已难以满足企业需求。越来越多企业开始选择新型海外专线解决方案,其中基于SD-WAN技术的企业级海外网络专线备受关注。这类服务不仅能保障跨国数据传输,还能根据业务需求灵活调整网络配置。接下来我们…...
阿里云服务器安装docker以及mysql数据库
(1) 官方下载路径 官方下载地址: Index of linux/static/stable/x86_64/阿里云镜像地址: https://mirrors.aliyun.com/docker-ce/下载最新的 Docker 二进制文件:wget https://download.docker.com/linux/static/stable/x86_64/docker-20.10.23.tgz登录到阿里云服务…...
力扣经典算法篇-5-多数元素(哈希统计,排序,摩尔投票法)
题干: 给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入:nums [3,2,3] 输出&…...
axios介绍以及配置
Axios 是一个基于 Promise 的 HTTP 客户端,用于浏览器和 Node.js 环境中进行 HTTP 请求。 一、特点与基本用法 1.特点 浏览器兼容性好:能在多种现代浏览器中使用,包括 Chrome、Firefox、Safari 等。支持 Promise API:基于 Prom…...
深入解析:HarmonyOS Design设计语言的核心理念
深入解析:HarmonyOS Design设计语言的核心理念 在当今数字化迅速发展的时代,用户对操作系统的体验要求越来越高。华为的HarmonyOS(鸿蒙操作系统)应运而生,旨在为用户提供全场景、全设备的智慧体验。其背后的设计语言—…...
大数据技术之Scala:特性、应用与生态系统
摘要 Scala 作为一门融合面向对象编程与函数式编程范式的编程语言,在大数据领域展现出独特优势。本文深入探讨 Scala 的核心特性,如函数式编程特性、类型系统以及与 Java 的兼容性等。同时,阐述其在大数据处理框架(如 Apache Spa…...
程序化广告行业(47/89):竞价指标剖析与流量对接要点
程序化广告行业(47/89):竞价指标剖析与流量对接要点 大家好!一直以来,我都希望能和大家一同深入探索程序化广告行业的奥秘,这也是我持续撰写这一系列博客的动力。今天,咱们接着来剖析程序化广告…...
dfs记忆化搜索刷题 + 总结
文章目录 记忆化搜索 vs 动态规划斐波那契数题解代码 不同路径题解代码 最长递增子序列题解代码 猜数字大小II题解代码 矩阵中的最长递增路径题解代码 总结 记忆化搜索 vs 动态规划 1. 记忆化搜索:有完全相同的问题/数据保存起来,带有备忘录的递归 2.记忆…...
vue2 全局封装axios统一管理api
在vue项目中,经常会使用到axios来与后台进行数据交互,axios丰富的api满足我们基本的需求。但是对于项目而言,每次都需要对异常进行捕获或者处理的话,代码会很繁重冗余。我们需要将其公共部分封装起来,比如异常处理&…...
大模型有哪些算法
大模型(Large-scale Models)通常指参数量大、架构复杂、在特定任务或领域表现出色的深度学习模型。这些模型的算法核心往往基于Transformer 架构及其变体,同时结合了大规模数据、硬件加速和优化技巧。以下是当前主流大模型及其核心算法的分类…...
【Linux】进程的详讲(中上)
目录 📖1.什么是进程? 📖2.自己写一个进程 📖3.操作系统与内存的关系 📖4.PCB(操作系统对进程的管理) 📖5.真正进程的组成 📖6.形成进程的过程 📖7、Linux环境下的进程知识 7.1 task_s…...
Python Cookbook-4.17 字典的并集与交集
任务 给定两个字典,需要找到两个字典都包含的键(交集),或者同时属于两个字典的键(并集)。 解决方案 有时,尤其是在Python2.3中,你会发现对字典的使用完全是对集合的一种具体化的体现。在这个要求中,只需要考虑键&am…...
优选算法的巧思之径:模拟专题
专栏:算法的魔法世界 个人主页:手握风云 目录 一、模拟 二、例题讲解 2.1. 替换所有的问号 2.2. 提莫攻击 2.3. Z字形变换 2.4. 外观数列 2.5. 数青蛙 一、模拟 模拟算法说简单点就是照葫芦画瓢,现在草稿纸上模拟一遍算法过程…...
【云服务器】在Linux CentOS 7上快速搭建我的世界 Minecraft 服务器搭建,并实现远程联机,详细教程
【云服务器】在Linux CentOS 7上快速搭建我的世界 Minecraft 服务器搭建,详细详细教程 一、 服务器介绍二、下载 Minecraft 服务端三、安装 JDK 21四、搭建服务器五、本地测试连接六、添加服务,并设置开机自启动 前言: 推荐使用云服务器部署&…...
文本分析(非结构化数据挖掘)——特征词选择(基于TF-IDF权值)
TF-IDF是一种用于信息检索和文本挖掘的常用加权算法,用于评估一个词在文档或语料库中的重要程度。它结合了词频(TF)和逆文档频率(IDF)两个指标,能够有效过滤掉常见词(如“的”、“是”等&#x…...
