双指针 -- 移动零、复写零、快乐数

news2024/11/13 10:26:40

目录

移动零

题解:

复写零

题解:

快乐数

题解:

盛最多水的容器


移动零

283. 移动零 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/move-zeroes/description/

题解:

题目要求我们把数组中的 0 放在数组的末尾,非零数按照原来的相对顺序,可以用快排的思想来解决这道题。

定义两个指针 dest 和 cur,这两个指针对数组进行了分类,下标从 0 到 dest 的数组区间存的是非零数,下标从 dest+1 到 cur 的数组区间存的是,下标从 cur+1 到数组的结尾部分还没有处理过的数,需要 cur 继续往后遍历来进行处理。

如何实现上面的分类呢?

从上面的分析上,我们发现 dest 是划分非零数和 0 的界限,arr[ dest ] 是非零数,arr[ dest+1 ] 就是 0,而 cur 的作用是为了找 0

  • 如果 cur 遍历到的数是非零数,那么交换 arr[ dest+1 ]  和 arr[ cur ] ,同时 dest++,dest 就可以继续发挥划分界限的作用!
  • 如果 cur 遍历到的数是 0,不必交换,直接 ++cur 。

用题目中的例1来进行分析:

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        for(int dest=-1,cur=0;cur<nums.size();++cur)
        {
            if(nums[cur]!=0)   
                swap(nums[++dest],nums[cur]);
        }
    }
};

复写零

1089. 复写零 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/duplicate-zeros/description/

题解:

由于题目要求在原地修改数组,所以我们不可以重新开辟一个新的数组进行异地修改,但是可以通过异地修改来整理本题的思路。

以示例 1 为例,复写之后超出数组范围的数将会被删掉。

 如果我们从前往后模拟复写过程,比如我们用 i 来遍历数组,当 arr[ i ] 为 0 时,让 arr[ i+1 ] 复写为 0,那么 arr[ i+1 ] 原本的数就被覆盖了,最终得到的答案一定是错误的。

所以采用从后往前的方式, 那么从后往前要从哪里开始遍历,才可以避免复写时发生数组越界呢?

我们可以先用两个指针来模拟一下复写过程,得出复写后的数组的最后一个数是谁。

指针 i 用来找出复写后的数组的最后一个数是谁,指针 top 用来遍历数组,

  • 如果 arr[ i ] == 0,那么 top += 2 ;
  • 如果 arr[ i ] != 0,那么 top++ ;

其实指针 i 是在模拟复写的过程,在找出复写后的元素是什么,而指针 top 是在模拟 arr[ i ] 复写后会怎么移动,指向 arr[ i ] 移动后的位置的下一个下标

当 top 越界时,说明复写过程已经模拟完成了,结束模拟,此时的 arr[ i ] 就是复写后的数组的最后一个元素

找到复写完的数组的最后一个元素后,就可以开始进行复写操作了,指针 j 从数组的最后一个元素开始遍历,

  • arr[ i ] !=0 ,此时 arr[ i ] 不需要复写,则  arr[ j ] = arr[ i ];
  • arr[ i ] ==0,此时 arr[ i ] 需要复写,则  arr[ j ] = arr[ i ] 之后,--j,把 0 再写一次

完成一次复写操作之后,把 i 和 j 都减 1 即可。

上面的模拟还存在一种特殊情况,如果复写后的最后一个数是 0 呢?

比如下面的数组,arr = [ 1, 0, 2, 3, 0, 4 ],先进行复写模拟:

可以发现复写后得到的数组的最后一个元素为 0 ,但是这个 0 是不需要复写的,或者说复写后的第二个 0 超出了数组的范围,被砍掉了。这时候再按照上面的复写过程,就会得到错误的结果。

所以我们需要在复写之前,对指针进行修正:

  • 如果复写后的数组的最后一个元素不是 0,则 top == n; 
  • 如果复写后的数组的最后一个元素为 0 ,才会导致 top == n+1。

 如果 top == n+1,则先把复写后的数组的最后一个元素填写为 0,然后指针 i 和 j 都向前移动一步,这样就可以保证复写后的数组的正确性。

 复写过程如下:

class Solution {
public:
    void duplicateZeros(vector<int>& arr) {
        //模拟复写过程,找出复写后数组的最后一个数
        int top=0,i=-1,n=arr.size();
        while(top<n)
        {
            i++;//i一个个遍历数组
            //top模拟复写后的情况
            if(!arr[i]) top+=2;//是0,要复写,所以+2
            else top++;//不是0,不用复写,所以+1
        }

        int j=n-1;
        if(top==n+1)//说明复写后的数组的最后一个元素为0
        {
            arr[n-1]=0;
            j--;    i--;
        }

        //开始复写
        while(j>=0)
        {
            arr[j]=arr[i]; --j;
            if(arr[i]==0)//复写
            {
                arr[j--]=0;
            }
            i--;
        }
    }
};

快乐数

202. 快乐数 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/happy-number/description/

题解:

由于 n 是 int 类型,int 类型下能表示的最大正整数为 2147483647,按照题目的要求,对于一个正整数,把正整数的每一位置的数的平方后相加,这个和的最大值和最小值是多少呢?

在 int 范围内,当正整数的每一位置的数都尽可能大时,平方和就可以达到最大值,当这个正整数为 19 9999 9999 时(29 9999 9999 已经超出 int 的范围了),平方和达到最大,为  81*9 + 1=730 。反之,当正整数的每一位置的数都尽可能小时,平方和就可以达到最小值,显然,平方和的最小值为 1。所以平方和的取值范围为 1 到 730 .

也就是说,根据抽屉原理,一个数 n 经过无数次 求每一位置的数的平方和 时,一定会存在重复的平方和,如果这个重复的平方和为 1,那么 n 就是快乐数,如果不是 1,那么 n 就不是快乐数!

那么我们怎样得到这个重复的平方和呢?

按照题目的暗示,求平方和的过程是一个循环,既然是循环,就可以按照快慢指针的思想(快指针的速度是慢指针的两倍),快指针比慢指针多求一次平方和,在一个循环中,快慢指针最终一定会相遇!当快慢指针相遇时,也就是出现了重复的平方和,如果这个重复的平方和为 1,那么 n 就是快乐数,如果不是 1,那么 n 就不是快乐数!

为什么初始化时慢指针为 n,快指针先求了一(两)次平方和,而不是让快慢指针都初始化为 n ?

因为我们用了 while 来模拟快慢指针的循环过程,当快慢指针相遇时,即 快慢指针相等时,while 循环结束,如果我们一开始就把快慢指针都初始化为 n,是没办法进入循环过程的!

class Solution {
public:
    int Pow(int num)
    {
        int ret=0;
        while(num)
        {
            ret+=pow(num%10,2);
            num/=10;
        }
        return ret;
    }
    bool isHappy(int n) {
        int fast=Pow(n),slow=n;
        //int fast=Pow(Pow(n)),slow=n; 也可以
        while(fast!=slow)
        {
            fast=Pow(Pow(fast)),slow=Pow(slow);
        }
        if(fast==1 && slow==1) return true;
        else return false;
    }
};

盛最多水的容器

11. 盛最多水的容器 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/container-with-most-water/description/

class Solution {
public:
    int maxArea(vector<int>& height) {
        int left=0,right=height.size()-1,ret=0;
        while(left<right)
        {
            int tmp=min(height[left],height[right])*(right-left);
            ret=max(tmp,ret);

            //移动指针
            if(height[left]>height[right]) --right;
            else ++left;
        }
        return ret;
    }
};

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

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

相关文章

大数据新视界 --大数据大厂之DevOps与大数据:加速数据驱动的业务发展

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

ReentrantLock实现原理

ReentrantLock是基于AQS实现的可重入锁&#xff0c;比synchronized更灵活&#xff0c;可以设置超时时间&#xff0c;可以中断&#xff0c;支持公平和非公平锁两种方式。公平锁获取锁的方式&#xff1a; 主要就是这三步 第一步&#xff1a;tryAcquire 先尝试获得锁 先获取state&…

Flux【真人模型】:高p高糊反向真实质感!网图风格的Lora模型,超逼真的AI美女大模型!

大家好&#xff0c;我是画画的小强 今天和大家分享一款基于Flux训练的网图风格的lora模型&#xff1a;墨幽-F.1-Lora-网图&#xff0c;该Lora模型由墨幽团队出品&#xff0c;旨在生成高p高糊的反向真实质感图片&#xff0c;而非真实摄影图片。不过&#xff0c;在自己出图过程中…

Linux操作系统 进程(3)

接上文 Linux进程优先级之后&#xff0c;我们了解到僵尸进程与孤儿进程的形成原因&#xff0c;既然是因为父进程没有接收子进程的退出状态导致的&#xff0c;那么我们该如何去获取子进程的退出状态呢&#xff1f;那本篇文章将围绕这个问题来解释进程。 环境 &#xff1a; vsco…

更高效的搜索工具,国内免费好用的AI智能搜索引擎工具

搜索引擎是我们获取信息的重要渠道&#xff0c;然而由于搜索引擎搜索结果存在较多的广告以及一些无关内容&#xff0c;这使我们的搜索效率变得更低效。小编就和大家分享几款国内免费好用的AI智能搜索工具&#xff0c;提高搜索效率。 1.开搜AI搜索 开搜AI搜索是一款基于深度学…

【学术会议:中国杭州,机器学习和计算机应用面临的新的挑战问题和研究方向】第五届机器学习与计算机应用国际学术会议(ICMLCA 2024)

您的学术研究值得被更多人看到&#xff01; 在这里&#xff0c;我为您提供精准的会议推荐&#xff0c;包括水利土木工程、计算机科学、地球科学、机械自动化、材料与制造技术、经管金融、人文社科等主流学科相关领域的国际会议。快速的稿件录用和高效的检索服务将确保您的研究…

30个小米集团芯片工程师岗位面试真题

在竞争激烈的半导体行业&#xff0c;小米集团作为全球知名的科技公司&#xff0c;对于芯片工程师的选拔标准自然也是极为严格。本篇分享一份《30个小米集团芯片工程师岗位面试真题》&#xff0c;通过对这30道真题的深入分析&#xff0c;我们可以一窥小米对于芯片设计人才的期待…

缓存数据和数据库数据一致性问题

根据以上的流程没有问题&#xff0c;但是当数据变更的时候&#xff0c;如何把缓存变到最新&#xff0c;使我们下面要讨论的问题 1. 更新数据库再更新缓存 场景&#xff1a;数据库更新成功&#xff0c;但缓存更新失败。 问题&#xff1a; 当缓存失效或过期时&#xff0c;读取…

Web后端服务平台解析漏洞与修复、文件包含漏洞详解

免责申明 本文仅是用于学习检测自己搭建的Web后端服务平台解析漏洞、文件包含漏洞的相关原理,请勿用在非法途径上,若将其用于非法目的,所造成的一切后果由您自行承担,产生的一切风险和后果与笔者无关;本文开始前请认真详细学习《‌中华人民共和国网络安全法》‌及其所在国…

阿贝云评测:免费虚拟主机和免费云服务器体验分享

最近我有幸体验了阿贝云提供的免费虚拟主机和免费云服务器&#xff0c;在这里分享一下我的使用体验。首先我想说的是&#xff0c;阿贝云的服务真的很不错。他们提供的免费虚拟主机性能稳定&#xff0c;速度快&#xff0c;对于刚开始建站的小伙伴来说是一个很好的选择。免费云服…

技术美术百人计划 | 《5.1.1 PBR-基于物理的材质》笔记

1. PBR定义-基于物理的材质 PBR&#xff0c;或者用更通俗一些的称呼是指基于物理的渲染(Physically Based Rendering)&#xff0c;它指的是一些在不同程度上都基于与现实世界的物理原理更相符的基本理论所构成的渲染技术的集合。 正因为基于物理的渲染目的便是为了使用一种更…

【Linux系统编程】第二十一弹---进程的地址空间

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、进程空间的地址 1.1、基本概念 1.2、代码分析 1.3、如何理解地址空间 1.4、进一步理解页表和写时拷贝 1.5、进一步理解…

基于SpringBoot+Vue+MySQL的智能物流管理系统

系统展示 系统背景 随着信息技术的飞速发展和电子商务的蓬勃兴起&#xff0c;智能物流管理系统的需求日益迫切。传统的物流管理方式已难以满足高效、精准、实时的管理需求。因此&#xff0c;基于SpringBoot、Vue和MySQL的智能物流管理系统应运而生。该系统旨在通过现代化的技术…

vue项目引入比较独特的字体的方法

引入字体的步骤 前言&#xff08;步骤一&#xff09;引入的文件OPPOSans-M.ttf,TencentSans-W3.ttf,TencentSans-W7.ttf,YouSheBiaoTiHei.ttf (步骤二)font.css(步骤三) 全局引入在使用的地方的展示效果展示 前言 公司这边开发一个可视化大屏&#xff0c;UI小姐姐设置了很多比…

2024年超好用的公司加密软件分享|十款企业防泄密软件推荐

在数字化时代&#xff0c;企业数据的安全性变得尤为重要。随着网络攻击和数据泄露事件的频发&#xff0c;企业需要采取有效的措施来保护敏感信息。加密软件作为一种重要的数据保护工具&#xff0c;能够帮助企业防止数据泄露和未经授权的访问。本文将为您推荐十款2024年超好用的…

Dockerfile部署xxljob

使用Dockerfile部署xxljob 1. 背景 我们在使用定时任务调度时&#xff0c;通常会使用xxljob容器化部署xxljob&#xff0c;通常使用 docker pull xuxueli/xxl-job-admin:2.4.0 拉取镜像并启动容器。这种方式对于x86架构服务器来说&#xff0c;没有任何问题。但是在arm架构的服…

什么是 IP 地址信誉?5 种改进方法

IP 地址声誉是营销中广泛使用的概念。它衡量 IP 地址的质量&#xff0c;这意味着您的电子邮件进入垃圾邮件或被完全阻止发送的可能性。 由于每个人都使用专用电子邮件提供商而不是直接通过 IP 地址进行通信&#xff0c;因此&#xff0c;这些服务可以跟踪和衡量发件人的行为质量…

玩机进阶教程-----MTK芯片机型 回读 备份 导出分区来制作线刷包 其中MT****_Android_scatter.txt的修改 分区的写入与否

在与一些小品牌机型定制系统过程中。其中一些机型定制导出分区制作线刷包。默认分区的写入与否要了解清楚。有些分区导出后在写入有可能会导致机型不开机或者卡第一屏的故障。这方面最基本的就是涉及mtk分区写入地址引导MT****_Android_scatter.txt的修改 通过博文了解 1----…

一文了解高速工业相机

超高速相机是工业相机的一种&#xff0c;一般高速相机指的是数字工业相机&#xff0c;其一般安装在机器流水线上代替人眼来做测量和判断&#xff0c;通过数字图像摄取目标转换成图像信号&#xff0c;传送给专用的图像处理系统。 超高速工业相机的采集速率> 50Gb/s&#xff…

AI取代程序员? or 成为10倍效能工程师!

Manuel Odendahl 是一位知名的人工智能和机器学习专家&#xff0c;尤其在计算机视觉和自然语言处理领域有显著贡献。他的研究涉及深度学习、图像识别和人机交互等方面&#xff0c;且在相关领域发表了多篇学术论文。 在这个人工智能快速发展的时代&#xff0c;程序员的工作方式正…