移动零+复写零+快乐数+盛最多水的容器+有效三角形的个数

news2025/4/25 22:50:40

前言

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++;
            else
                fast += 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;
    }
};

我们来看一眼运行结果

那么今天的五道算法题就到此为止,我们期待下一期!

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

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

相关文章

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) 很难查明根本原…

学习笔记—数据结构—二叉树(链式)

目录 二叉树&#xff08;链式&#xff09; 概念 结构 初始化 遍历 前序遍历 中序遍历 后序遍历 层序遍历 结点个数 叶子结点个数 第k层结点个数 深度/高度 查找值为x的结点 销毁 判断是否为完整二叉树 总结 头文件Tree.h Tree.c 测试文件test.c 补充文件Qu…

深入理解指针5

sizeof和strlen的对比 sizeof的功能 **sizeof是**** 操作符****&#xff0c;用来**** 计算****变量或类型或数组所占**** 内存空间大小****&#xff0c;**** 单位是字节&#xff0c;****他不管内存里是什么数据** int main() {printf("%zd\n", sizeof(char));p…

一文详解QT环境搭建:Windows使用CLion配置QT开发环境

在当今的软件开发领域&#xff0c;跨平台应用的需求日益增长&#xff0c;Qt作为一款流行的C图形用户界面库&#xff0c;因其强大的功能和易用性而备受开发者青睐。与此同时&#xff0c;CLion作为一款专为C/C打造的强大IDE&#xff0c;提供了丰富的特性和高效的编码体验。本文将…

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/…

多段圆弧拟合离散点实现切线连续

使用多段圆弧来拟合一个由离散点组成的曲线,并且保证切线连续。也就是说&#xff0c;生成的每一段圆弧之间在连接点处必须有一阶导数连续&#xff0c;也就是切线方向相同。 点集分割 确保每个段的终点是下一段的起点&#xff0c;相邻段共享连接点&#xff0c;避免连接点位于数…

【蓝桥杯】第十四届C++B组省赛

⭐️个人主页&#xff1a;小羊 ⭐️所属专栏&#xff1a;蓝桥杯 很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~ 目录 试题A&#xff1a;日期统计试题B&#xff1a;01串的熵试题C&#xff1a;冶炼金属试题D&#xff1a;飞机降落试题E&#xff1a;接…

企业级海外网络专线行业应用案例及服务商推荐

在全球化业务快速发展的今天&#xff0c;传统网络技术已难以满足企业需求。越来越多企业开始选择新型海外专线解决方案&#xff0c;其中基于SD-WAN技术的企业级海外网络专线备受关注。这类服务不仅能保障跨国数据传输&#xff0c;还能根据业务需求灵活调整网络配置。接下来我们…

阿里云服务器安装docker以及mysql数据库

(1) 官方下载路径 官方下载地址: Index of linux/static/stable/x86_64/阿里云镜像地址: https://mirrors.aliyun.com/docker-ce/下载最新的 Docker 二进制文件&#xff1a;wget https://download.docker.com/linux/static/stable/x86_64/docker-20.10.23.tgz登录到阿里云服务…

深入解析:HarmonyOS Design设计语言的核心理念

深入解析&#xff1a;HarmonyOS Design设计语言的核心理念 在当今数字化迅速发展的时代&#xff0c;用户对操作系统的体验要求越来越高。华为的HarmonyOS&#xff08;鸿蒙操作系统&#xff09;应运而生&#xff0c;旨在为用户提供全场景、全设备的智慧体验。其背后的设计语言—…

dfs记忆化搜索刷题 + 总结

文章目录 记忆化搜索 vs 动态规划斐波那契数题解代码 不同路径题解代码 最长递增子序列题解代码 猜数字大小II题解代码 矩阵中的最长递增路径题解代码 总结 记忆化搜索 vs 动态规划 1. 记忆化搜索&#xff1a;有完全相同的问题/数据保存起来&#xff0c;带有备忘录的递归 2.记忆…

【Linux】进程的详讲(中上)

目录 &#x1f4d6;1.什么是进程? &#x1f4d6;2.自己写一个进程 &#x1f4d6;3.操作系统与内存的关系 &#x1f4d6;4.PCB(操作系统对进程的管理) &#x1f4d6;5.真正进程的组成 &#x1f4d6;6.形成进程的过程 &#x1f4d6;7、Linux环境下的进程知识 7.1 task_s…

优选算法的巧思之径:模拟专题

专栏&#xff1a;算法的魔法世界 个人主页&#xff1a;手握风云 目录 一、模拟 二、例题讲解 2.1. 替换所有的问号 2.2. 提莫攻击 2.3. Z字形变换 2.4. 外观数列 2.5. 数青蛙 一、模拟 模拟算法说简单点就是照葫芦画瓢&#xff0c;现在草稿纸上模拟一遍算法过程&#xf…

【云服务器】在Linux CentOS 7上快速搭建我的世界 Minecraft 服务器搭建,并实现远程联机,详细教程

【云服务器】在Linux CentOS 7上快速搭建我的世界 Minecraft 服务器搭建&#xff0c;详细详细教程 一、 服务器介绍二、下载 Minecraft 服务端三、安装 JDK 21四、搭建服务器五、本地测试连接六、添加服务&#xff0c;并设置开机自启动 前言&#xff1a; 推荐使用云服务器部署&…

文本分析(非结构化数据挖掘)——特征词选择(基于TF-IDF权值)

TF-IDF是一种用于信息检索和文本挖掘的常用加权算法&#xff0c;用于评估一个词在文档或语料库中的重要程度。它结合了词频&#xff08;TF&#xff09;和逆文档频率&#xff08;IDF&#xff09;两个指标&#xff0c;能够有效过滤掉常见词&#xff08;如“的”、“是”等&#x…

【JavaSE】小练习 —— 图书管理系统

【JavaSE】JavaSE小练习 —— 图书管理系统 一、系统功能二、涉及的知识点三、业务逻辑四、代码实现4.1 book 包4.2 user 包4.3 Main 类4.4 完善管理员菜单和普通用户菜单4.5 接着4.4的管理员菜单和普通用户菜单&#xff0c;进行操作选择&#xff08;1查找图书、2借阅图书.....…

多线程(多线程案例)(续~)

目录 一、单例模式 1. 饿汉模式 2. 懒汉模式 二、阻塞队列 1. 阻塞队列是什么 2. 生产者消费者模型 3. 标准库中的阻塞队列 4. 自实现阻塞队列 三、定时器 1. 定时器是什么 2. 标准库中的定时器 欢迎观看我滴上一篇关于 多线程的博客呀&#xff0c;直达地址&#xf…

一个判断A股交易状态的python脚本

最近在做股票数据相关的项目&#xff0c;需要用到判断某一天某个时刻A股的状态&#xff0c;比如休市&#xff0c;收盘&#xff0c;交易中等&#xff0c;发动脑筋想了一下&#xff0c;这个其实还是比较简单的&#xff0c;这里我把实现方法分享给大家。 思路 当天是否休市 对于某…

闪记(FlashNote):让灵感快速成文的轻量级笔记工具

闪记&#xff08;FlashNote&#xff09;&#xff1a;让灵感快速成文的轻量级笔记工具 你是否经常遇到这样的情况&#xff1a;桌面上放了一大堆的新建123.txt&#xff0c;想记录一个想法&#xff0c;应该是一键开个一个快捷键然后瞬间记录就自动保存了&#xff0c;现在的很多笔记…