双指齐下:那晚我与算法的不解之缘

在这里插入图片描述

公主请阅

  • 1.快乐数
    • 1.1题目说明
      • 示例 1
      • 示例 2
    • 1.3题目分析
    • 1.4代码部分
    • 1.5代码解析
  • 2.复写0
    • 2.1题目说明
      • 示例 1
      • 示例 2
    • 2.2题目分析
    • 2.3代码部分
    • 2.4代码解析

1.快乐数

在这里插入图片描述
题目传送门

1.1题目说明

编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」定义为

  • 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
  • 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
  • 如果这个过程 结果为 1,那么这个数就是快乐数。

如果 n 是快乐数就返回 true;如果不是,则返回 false


示例 1

输入n = 19
输出true
解释
1² + 9² = 82
8² + 2² = 68
6² + 8² = 100
1² + 0² + 0² = 1


示例 2

输入n = 2
输出false

1.3题目分析

在这里插入图片描述
我们这个题类似于判断链表是否有环

我们这里的两种情况,一种是最后都是1,一种是进行不同数字之间的循环

那么我们在解决快慢双指针的时候用到的就是快慢双指针的方法

1.定义快慢指针

2.慢指针每次向后移动一步,快指针向后每次移动两步

3.判断相遇的时候的值就行了,

我们在链表中利用快慢指针进行不同速度的走,看看最后我们的两个指针能不能相遇,如果相遇了的话,那么这个就是带环的链表

这个题的话我们仅仅需要判断我们相遇的的值是不是1

我么可以将数字定义为指针

我们这里一开始可以将指针定义给2,然后下一次就是4,那么现在的slow就指向了4

那么这个slow就被修改了

其实这个题有可能存在第三种情况的,就是一直进行变化,没有循环


1.4代码部分

class Solution {
public:
    int bitSum(int n)//返回n这个数每一位上面的平方和
    {
        int sum=0;
        while(n)
        {
            int t=n%10;//将最后一位拿出来
            sum+=t*t;
            n/=10;
        }
        return sum;
    }
    bool isHappy(int n)
    {
        int slow=n,fast=bitSum(n);//让fast指针指向这个第二个数字,就是第一个数字所有位上的数字的平方之和
        while(slow!=fast)
        {
            slow=bitSum(slow);
            fast=bitSum(bitSum(fast));//快指针走两步
        }
        //这里连个指针就相遇了
        return slow==1;//如果等于1的话就是快乐数,不等于1就不是快乐数了
    }
};

1.5代码解析

我们先写出一个计算一个数的每一位上的数字的平方之和的函数,这里我们是bitSum来实现这个功能

然后我们在主函数中进行快慢指针的定义,快指针走两步,慢指针走一步,直到最后的数值相等了

那么这个时候我们只需要判断这个数字是不是1就行了,是1的话就返回true,不是1的话就返回这个0


2.复写0

在这里插入图片描述
题目传送门


2.1题目说明

从图片中提取的信息如下:

给你一个长度固定的整数数组 arr,请你将数组中出现的每个零都复写一遍,并将其余的元素向右平移。

注意:请不要在超过该数组长度的情况下插入元素。请对输入的数组 就地 进行上述修改,不要从函数返回任何东西。


示例 1

输入arr = [1, 0, 2, 3, 0, 4, 5, 0]
输出[1, 0, 0, 2, 3, 0, 0, 4]
解释:调用函数后,输入的数组将修改为 [1, 0, 0, 2, 3, 0, 0, 4]


示例 2

输入arr = [1, 2, 3]
输出[1, 2, 3]
解释:调用函数后,输入的数组将修改为 [1, 2, 3]


2.2题目分析

如果是非0就写一遍,如果遇到的是0的话,就写两遍

我们这里同样采用双指针解法

我们创建一个新的数组,cur指针指向原数组的第一个元素,从左到右进行一个扫描的操作

然后我们的dest指向新数组的第一个元素

cur在遍历数组的时候会遇到两种情况,一种是0,一种是非0,那么我们就需要分情况讨论了

在这里插入图片描述
这种是异地操作,那么我们如何改成就地操作呢?

就是我们不用两个数组,将这两个指针定义在一个数组中

如何我们利用两个指针从左向右进行操作的话是会存在数据覆盖的

然后后面的数字全部被覆盖为0了

所以我们从右边开始进行运算

在这里插入图片描述
1.先找到最后一个复写的数

  • 双指针算法:先定义cur指向第一个数,然后dest指向-1,然后cur从前完后进行数组的遍历操作,决定这个dest向后移动一步还是两步

  • 1.1.我们先判断cur指向的数是0还是非0,

  • 1.2.根据cur位置的值决定dest向后移动一步或者是两步。如果是非0的话我们dest向后移动一步,如果是0的话就移动两步

  • 1.3.判断一下dest是否已经到结束为止

  • 1.4.cur++

经过这四步操作我们就能得到下面的指针的指向

在这里插入图片描述
这个时候我们就能发现此时的cur是我们需要复写的数,

存在特例,如果是这样的话就会存在特例,dest就会存在越界的现象

如果是越界访问的话,我们直接就是会进行报错的

cur的位置是没问题的,但是我们的dest是会存在问题的

1.5处理边界情况:越界的情况就是cur指向的数是0的情况,然后dest走了两步,然后因为走了一步就到最后的位置了,再走一步就到了边界之外了

所以我么需要将n-1位置的值修改为0,然后dest-=2 cur--

2.从后向前完成复写操作
先找到这个最后一个我们需要进行复写操作的值

找到之后我们将边界情况处理下

然后我们就从后往前进行复写的操作

这里虽然是两个while循环,但是常数循环的话时间复杂度是o(1)

空间复杂度是o(1)


2.3代码部分

class Solution {
public:
    void duplicateZeros(vector<int>& arr)
    {
        //1.找到最后一个复写的数
        int cur=0,dest=-1,n=arr.size();
        while(cur<n)
        {
            if(arr[cur])//非0的情况,dest向后走一位
            {
                dest++;
            }
            else//遇到0就走两位
            {
                dest+=2;
            }
            if(dest>=n-1) //越界
            {
                break;//这个时候的cur指向的值就是我们最后复写的数,那么我们就退出就行了
            }
            cur++;//这个时候我们的dest没有越界,我们的cur++,继续用往后找            
        }
        //2.处理边界情况
        if(dest==n)//就是最后的时候cur指向的数是0,然后dest多向后面移动了一步
        {
            arr[n-1]=0;
            cur--;
            dest-=2;
            //让cur往坐走一步,dest望左走两步
        }
        //3.从后向前完成复写的操作
        while(cur>=0)
        {
            if(arr[cur])//当前的位置不是0,我们只需要将当前的值抄到dest位置上
            {
                arr[dest--]=arr[cur--];
              //先用dest和cur再--
                //抄完之后就继续往左边走,--操作
            }
            else//是0的情况下
            {
                //将两个位置都复写成为0,然后dest每次都--
                arr[dest--]=0;
                arr[dest--]=0;
                //到这里我们的dest已经减了两次了
                cur--;
            }
        }

    }
};

2.4代码解析

在这个代码中,我们先利用双指针从左到右遍历整个数组,去找到这个数组中最后一个复写的数字
我们先开始将cur定义为0,dest定义为-1,
然后我们利用这个while循环进行遍历这个数组
遍历的条件是cur的大小小于这个数组的大小,假设数组的元素个数为n,那么我们的cur的大小要小于ncur最大的值就是n-1,我们在循环里面进行cur指向的数据的判断,如果指向的数据是非0的话,我们的dest就往后面走一步,如果遇到的是0的话我们的dest就走两步
然后如果我们的dest>=n-1的话,就说明我们的dest已经越界了,那么此时的cur指向的值就是我们最后复写的数,那么我们退出就行了

然后我们这个循环里面最后就让我们的cur走一步

那么这个时候我们的cur已经指向最后一个我们需要复写的数了,那么我们需要判断下边界情况并进行处理下
如果经过上面的循环后我们的dest此时等于n,就是在这个数组外面,这个是因为当我们数组最后倒数第二个数是0的话,然后cur指向了这个数,然后触发了dest往后面走了两步出界了,然后我们就需要进行处理下,让dest回到正常的范围里面去
我们直接让这个数组最后一个数变为0,然后cur--dest-=2,cur退一步,dest退两步,然后就回到了正常的范围里面了

最后我们就从后往前进行复写的操作,遇到0就写两遍,非0就写一遍
我们在while这个循环里面,循环条件是cur>=0不出界就行了
我们在循环里面进行判断cur指向的当前位置是不是0,如果是非0的话我们就让destcur当前的指向的两个数交换位置,
然后都进行减减的操作,往左边走,
如果cur指向的是0的话,我们就将dest当前的位置变为0,然后dest往左边走一个位置,然后这个位置的数也变成0,然后dest再往左边走一位进行后面的判断操作
到这里我们的dest已经走了两次了,那么我们的cur也是需要走一次的

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

探索 Blob 对象的应用场景和实例分析

一. 引言 当我们在开发 Web 应用程序时&#xff0c;常常会遇到需要处理二进制数据的情况。这时&#xff0c;Blob&#xff08;Binary Large Object&#xff09;对象就成为了一个非常有用的工具。Blob 对象可以用来表示一段二进制数据&#xff0c;它可以存储和操作各种类型的数据…

FPAG学习(5)-三种方法实现LED流水灯

目录 1.移位实现LED流水灯 1.1创建工程及源文件代码 1.1.1源代码 1.1.2仿真代码 1.1.3仿真 1.2实验结果 1.2.1总结 2.循环移位实现LED流水灯 3.38译码器实现LED流水灯 3.1原理 3.2源程序 1.移位实现LED流水灯 1.1创建工程及源文件代码 1.1.1源代码 利用计数器计数到…

Python网络爬虫从入门到实战

目录 引言 一、网络爬虫的概念 二、 网络爬虫的基本工作流程 &#xff08;一&#xff09;过程&#xff1a; &#xff08;二&#xff09;安装requests模块和beautifulsoup4模块 &#xff08;三&#xff09;requests库的使用 1、requests库的基本介绍 2、导入requests库的…

IO作业代码

问题 通过 fwrite和 fread去拷贝 文件到另外一个文件上 #include<myhead.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include<errno.h> #include<time.h> int main(int argc, const char *argv[]) { FILE *fp fo…

新款任天堂switch游戏机方案,支持4K60HZ投屏方案,显示器,手柄方案

据传任天堂将推出新的一代的switch掌机&#xff0c;而新款掌机将支持4K60HZ投屏 都2402年了再做1080P确实有点不太象话了 4K60HZ相较于1080P能够提升很多游戏体验&#xff0c;这时不管是HDMI显示器或者是VR眼睛清晰度都会让人舒服很多。 不过新一代的任天堂似乎也在PD协议上…

答题pk小程序的技术特点和性能优势分析

答题小程序是一种在移动设备上运行的应用程序&#xff0c;旨在提供各种类型的答题体验。以下是答题小程序的一些特点和优势&#xff1a; 一、特点 多样化的题目类型&#xff1a; 包括选择题、填空题、判断题等常见题型&#xff0c;还可能有简答题、论述题等更具挑战性的题型。…

qt+opengl 实现纹理贴图,平移旋转,绘制三角形,方形

1 首先qt 已经封装了opengl&#xff0c;那么我们就可以直接用了&#xff0c;这里面有三个函数需要继承 virtual void initializeGL() override; virtual void resizeGL(int w,int h) override; virtual void paintGL() override; 这三个函数是实现opengl的重要函数。 2 我们…

arp欺骗及其实验

ARP欺骗&#xff08;ARP Spoofing&#xff09;是一种网络攻击技术&#xff0c;攻击者通过伪造ARP&#xff08;地址解析协议&#xff09;消息&#xff0c;将其MAC地址与目标IP地址关联&#xff0c;从而实现对网络流量的截获、篡改或重定向。以下是ARP欺骗的详细信息&#xff1a;…

【JVM】—Java内存区域详解

Java内存区域详解 ⭐⭐⭐⭐⭐⭐ Github主页&#x1f449;https://github.com/A-BigTree 笔记链接&#x1f449;https://github.com/A-BigTree/Code_Learning ⭐⭐⭐⭐⭐⭐ 如果可以&#xff0c;麻烦各位看官顺手点个star~&#x1f60a; 文章目录 Java内存区域详解1 线程私有1…

Linux系统:Ubuntu上安装Chrome浏览器

Ubuntu系统版本&#xff1a;23.04 在Ubuntu系统上安装Google Chrome浏览器&#xff0c;可以通过以下步骤进行&#xff1a; 终端输入以下命令&#xff0c;先更新软件源&#xff1a; sudo apt update 或 sudo apt upgrade终端输入以下命令&#xff0c;下载最新的Google Chrome .…

瑞芯微RK3566/RK3568 Android11使用OTA升级固件方法,深圳触觉智能鸿蒙开发板演示,备战第九届华为ICT大赛

本文介绍瑞芯微RK3566/RK3568在Android11系统OTA升级固件方法&#xff0c;使用触觉智能的Purple Pi OH鸿蒙开发板演示&#xff0c;搭载了瑞芯微RK3566&#xff0c;Laval官方社区主荐&#xff01; 1、OTA包生成 在源码根目录上执行以下命令编译OTA包 # make installclean # …

Docker实践与应用举例

目录 1. 引言 2. Docker的基本概念 2.1 什么是Docker容器 2.2 Docker镜像 2.3 Docker架构 3. Docker的应用场景 3.1 开发与测试环境的隔离 3.2 持续集成与持续交付&#xff08;CI/CD&#xff09; 3.3 微服务架构 4. Docker的实践案例 4.1 部署Nginx反向代理 4.2 使用…

端到端的开源OCR模型:GOT-OCR-2.0,支持场景文本、文档、乐谱、图表、数学公式等内容识别!

今天给大家分享一个端到端的开源 OCR 模型&#xff0c;号称 OCR 2.0&#xff01; 支持场景文本、文档、乐谱、图表、数学公式等内容识别&#xff0c;拿到了 BLEU 0.972 高分。 从给出的演示图来看&#xff0c;一些非常复杂的数学公式都能正确的识别&#xff0c;颇为强大。模型…

文件IO(Linux文件IO)

前言 本文介绍Linux系统下自带的文件IO的函数。 Linux文件IO相关函数 open函数 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode)…

JAVA就业笔记8——第二阶段(5)

课程须知 A类知识&#xff1a;工作和面试常用&#xff0c;代码必须要手敲&#xff0c;需要掌握。 B类知识&#xff1a;面试会问道&#xff0c;工作不常用&#xff0c;代码不需要手敲&#xff0c;理解能正确表达即可。 C类知识&#xff1a;工作和面试不常用&#xff0c;代码不…

Spire.PDF for .NET【页面设置】演示:在 C#/VB.NET 中创建 PDF 小册子

当人们打印大型 PDF 文档时&#xff0c;PDF 小册子非常有用。它在书籍、报纸和杂志编辑中特别受欢迎。本节将介绍一种通过C#、VB.NET 中的.NET PDF组件创建 PDF 小册子的非常简单的方法。 Spire.PDF for .NET 是一款独立 PDF 控件&#xff0c;用于 .NET 程序中创建、编辑和操作…

进程和作业管理

1.概念 &#xff08;1&#xff09;进程 进程是指一个具有独立功能的程序的一次运行过程&#xff0c;也是系统进行资源分配和调度的基本单位&#xff0c;即每个程序模块和它执行时所处理的数据组成了进程。进程虽不是程序&#xff0c;但由程序产生。进程与程序的区别在于&#…

中国联通目前规模最大的境外综合性通信枢纽大楼

中国联通&#xff08;香港&#xff09;将军澳智 云数据中心&#xff1a;打造境外通信服务新标杆 在数字化浪潮席卷全球的今天&#xff0c;数据中心作为信息社会的基石&#xff0c;其重要性日益凸显。中国联通&#xff08;香港&#xff09;将军澳智 云数据中心&#xff0c;作…

基于django的代理商订单管理系统

基于Django的代理商订单管理系统——高效助力代理商管理 在如今企业业务日益复杂的环境下&#xff0c;如何高效地管理代理商订单成为不可或缺的环节。我们推出了一款基于Django框架的代理商订单管理系统&#xff0c;专为企业的订单管理及返利控制设计&#xff0c;为企业与代理…

uniapp-uniapp + vue3 + pinia 搭建uniapp模板

使用技术 ⚡️uni-app, Vue3, Vite, pnpm &#x1f4e6; 组件自动化引入 &#x1f34d; 使用 Pinia 的状态管理 &#x1f3a8; tailwindcss - 高性能且极具灵活性的即时原子化 CSS 引擎 &#x1f603; 各种图标集为你所用 &#x1f525; 使用 新的 <script setup> …