【代码随想录】刷题Day5

1.链表重复节点删除

82. 删除排序链表中的重复元素 II

前后指针实现

1.做这道题最大的感受就是:不要觉得开辟空间浪费,多用临时变量去记录。越精确越容易成功

2.首先没有节点或者一个节点直接返回

3.因为头部会出现一样元素的情况,以至于我不认为直接在head上改变是一个很好的选择,所以我重新构建了一个节点作为临时头节点,它用来标记我们需要改变的链表

4.由于还是老生常谈的删除,依然需要节点的前驱,以至于我们创造了三个标记节点,prev标记在head前也就是ret位置,cur为head,next为head的下一个节点

5.整体的删除思路其实就是让next往下走,所以判断循环结束就是看next是不是空。

6.next往后走,要不要删除就是看跟cur是否一样。其实就两种情况,cur->next就是next,说明此时next没有往后走,说明前后不一样,说明不要删除cur。cur->nex不是next,说明next往后走了,需要删除prev到next之间的所有节点

7.如果需要删除的,那么更新前驱prev->next指向next,因为prev到next之间都删除。后续就是循环删除节点:cur指向的就是删除的节点,那么我们先保存到tmp中,cur往后走,删除tmp,直到cur与next在同一个位置

8.如果是添加,其实很简单,就是前驱prev往后走

9.不管是删除还是添加,我们还要往后遍历,所以cur走到next位置,随后检查cur的下一个是否为空,空了就说明遍历完了,那退出就行;没有,则把next继续赋值为cur->next

10.最后循环结束了,head更新为ret的下一个,是否ret,返回head即可

class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        if(head==nullptr||head->next==nullptr)
            return head;
        ListNode* ret = new ListNode(0,head);
        ListNode* prev = ret;
        ListNode* cur = head;
        ListNode* next = head->next;
        while(next)
        {
            while(next&&cur->val==next->val)
                next=next->next;
            if(cur->next!=next)
            {
                prev->next=next;
                while(cur==next)
                {
                    ListNode* tmp = cur;
                    cur=cur->next;
                    delete tmp;
                }
            } 
            else
                prev=cur;
            cur=next;
            if(cur==nullptr||cur->next==nullptr)
                break;
            
            next=cur->next;
        }
        head=ret->next;
        delete ret;
        return head;
    }
};

依然熟悉的前驱,所以我选择递归

递归实现

1.其实之前我们就讲过递归删除节点的操作了,但是这里最烦的应该有两个点:一个是连续删除节点 二是更新头节点,而且是更新跨度很大。这些就是关键,搞定这些就能成功

2.首先,头节点为空或者只有一个节点就退出,不需要执行任何东西

3.递归函数的参数到底怎么设计是一个值得考虑的问题:因为头节点可能会变,所以要传入一个头节点并且要引用接收;前驱和删除标记点都要,需要有一个cur和prev;删除一个节点后如何告诉上层也要删除呢,我们选择传入一个int类型,0为不删除,1为删除,因为上层要知道,所以我们传入引用的变量

4.进入递归,首先是到底部,cur为空到底,返回。那么其他情况就递归往下走

5.走到递归后,我们需要执行删除:

先不考虑头节点怎么办,我们考虑普通的中间点怎么删除

首先是前驱和现在的数一样,这种我们就要删除cur位置,不过前驱要连接cur的next。然后释放掉该删除的点。

其次,我们删除的操作其实只针对某点,但是我们还想它的前驱也被删除,所以我们需要在cur删除这层把target变为1,告诉上层(也就是这层prev)cur指向也要删除。那么我们大条件就是target为1时也要删除。

不过删除掉一系列相同的节点后,我们要停止删除,那么判断的一句就是prev的值和cur 的值是否一样,一样就给target变为0

6.最后我们要分析头节点位置,如果prev等于nullptr就是到头节点了,我们依然用到target是否为1判断头节点位置是否要删除并且更新,为1,head更新为cur的next,删除该节点。如果不用删直接退出。

class Solution {
public:
    void _delDupR(ListNode*& head, ListNode* prev, ListNode* cur, int& target)
    {
        if (cur == nullptr)
            return;
        _delDupR(head, cur, cur->next, target);
        if (prev == nullptr)
        {
            if (target == 1)
            {
                head = cur->next;
                delete cur;
            }
            return;
        }
        if (target == 1 || prev->val == cur->val)
        {
            target = 1;
            ListNode* tmp = cur;
            prev->next = cur->next;
            cur = cur->next;
            if(prev->val!=tmp->val)
                target = 0;
            delete tmp; 
        }
    }

    ListNode* deleteDuplicates(ListNode* head) {
        if (head == nullptr || head->next == nullptr)
            return head;
        int target = 0;
        _delDupR(head, nullptr, head, target);
        return head;
    }
};

2.双链

​​​​​​328. 奇偶链表

最讨厌这种双指针然后换来换去的

1.空节点,一个节点和两个节点的不需要进行操作,直接返回

2.所以链表至少三个节点,我们给出head1标记单数链表开头也就是head;head2标记双数开头也就是head的next;前驱prev1和prev2都指向当前各自头节点;改动节点cur1和cur2也指向各自头节点

3.先不写循环的终止条件,我们先调整节点;cur1要指向prev2的next,随后cur2是cur1的next;这里就要分析了,cur1的下一个为空怎么办。所以cur2要给两个情况,一个是cur的next为空,cur2为nullptr;一个是cur的next有节点,cur2是cur1的next

4.随后前驱指向对应的调整cur,更新prev

5.我们知道cur2根据cur1定,那么我们其实只定cur1作为判断条件就行,因为链表至少三个数,因此按照上面的逻辑运行下来,cur1->next可能为空,cur1->next->next也可能为空,所以看这里条件即可判断是否停止循环

class Solution {
public:
    ListNode* oddEvenList(ListNode* head) {
        if(head==nullptr||head->next==nullptr||head->next->next==nullptr)
            return head;
        ListNode* head1 = head;
        ListNode* prev1 = head;
        ListNode* cur1 = head;
        ListNode* head2 = head->next;
        ListNode* prev2 = head2;
        ListNode* cur2 = head2;
        while(cur1->next&&cur1->next->next)
        {
            cur1=prev2->next;
            if(cur1->next==nullptr)
                cur2=nullptr;
            else
                cur2=cur1->next;
            prev1->next=cur1;
            prev1=prev1->next;
            prev2->next=cur2;
            prev2=prev2->next;
        }
        cur1->next=head2;
        return head;
    }
};

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

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

相关文章

Transformer 位置编码代码解析

Transformer 位置编码代码解析 Transformer 的 Multi-Head-Attention 无法判断各个编码的位置信息。因此 Attention is all you need 中加入三角函数位置编码(sinusoidal position embedding),表达形式为: P E ( p o s , 2 i ) …

springboot +flowable,处理 flowable 的用户和用户组(一)

一.简介 对于flowable是什么以及关于此框架的具体信息可以参看此项目的官方文档:https://www.flowable.org/docs/userguide/index.html Flowable is a light-weight business process engine written in Java.这是官网文档对此框架的完美解释:Flowable…

养老保障金查询系统【GUI/Swing+MySQL】(Java课设)

系统类型 Swing窗口类型Mysql数据库存储数据 使用范围 适合作为Java课设!!! 部署环境 jdk1.8Mysql8.0Idea或eclipsejdbc 运行效果 本系统源码地址:https://download.csdn.net/download/qq_50954361/87700421 更多系统资源库…

Redis入门学习笔记【二】Redis缓存

目录 一、Redis缓存 二、Redis使用缓存遇到的问题 2.1 数据一致性 2.2缓存雪崩 2.3 缓存穿透 2.4 缓存击穿 一、Redis缓存 数据缓存是Redis最重要的一个场景,为缓存而生,在springboot中,一般有两种使用方式: 直接通过RedisT…

【无人机】无人机平台的非移动 GPS 干扰器进行位置估计的多种传感器融合算法的性能分析(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

leetcode142_环形链表 II

文章目录 题目详情分析Java完整代码 题目详情 给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给…

「数据架构」MDM实现失败的主要原因

我经常参与一个组织的MDM程序,当他们在一个失败的项目之后向InfoTrellis请求帮助进行清理,或者开始尝试X,以实现对某些人来说非常困难的目标时。主数据管理实现失败的原因有很多,但是没有一个是由于在这些场景中使用的责备游戏的原…

MySQL-中间件mycat(一)

目录 🍁mycat基础概念 🍁Mycat安装部署 🍃初始环境 🍃测试环境 🍃下载安装 🍃修改配置文件 🍃启动mycat 🍃测试连接 🦐博客主页:大虾好吃吗的博客 &#x1f9…

找网站绝对路径

目录 Linux系统 目标出网。且命令有回显 目标出网,命令无回显 目标不出网,命令无回显 Windows系统 目标出网,命令有回显 目标出网,命令无回显 目标不出网,命令无回显 Linux系统 目标出网。且命令有回显 find …

gpt在线使用-免费的 GPT在哪下载

免费的 GPT(Generative Pre-trained Transformer) 。现在您可以免费体验我们的 GPT 技术,来让您的业务或项目更加智能。 GPT 是一种基于最前沿的自然语言处理技术,它展现出了令人惊叹的预测能力和交互性能。我们的 GPT 是在世界顶…

SQL Compliance Manager Crack

SQL Compliance Manager Crack 新的SQL CM云代理-扩展了当前SQL CM代理的功能,以支持EC2上Microsoft SQL服务器的远程审核。允许用户添加在共享网络位置上活动的SQL Server,以写入/读取数据并支持DBaaS SQL Server实例。云代理包含与当前SQL代理相同的行…

被chatGPT割了一块钱韭菜

大家好,才是真的好。 chatGPT热度一直上升,让我萌生了一个胆大而创新的想法, 把chatGPT嵌入到Notes客户机中来玩。 考虑到我已经下载了一个chatGPT的Notes应用(请见《ChatGPT APIs for HCL DOMINO》),想着…

No.045<软考>《(高项)备考大全》【专项1】《案例分析 - 简介、方法、技巧、理论》

《案例分析》 1 专项介绍1.1 考试分析1.2 试卷参考1.3 题型分析 2 案例分析答题技巧2.1 考试6要2.2 三不要—可以2.3 其他技巧 3 案例中的万金油4 各领域中的重要工具与输出5 案例分析答题技巧6 案例分析理论题历年考点分析6.1 一般知识和科研立项6.2 整体、范围、需求6.3 进度…

我想知道,就目前形势而言,学java好还是C++好?

前言 就现实点看看,可以对比现在Java和C的市场占有率,可以看到,到目前为止,Java在国内编程语言的市场仍然是占据着大头,在招聘当中Java的人数占有率仍然是遥遥领先于C,Java目前开阔的市场以及其巨大的岗位…

风光场景削减及源荷不确定性的虚拟电厂随机优化调度研究(Matlab代码实现)

💥 💥 💞 💞 欢迎来到本博客 ❤️ ❤️ 💥 💥 🏆 博主优势: 🌞 🌞 🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 …

Python小姿势 - ###### 随机选取的知识点:Python日期时间处理

随机选取的知识点:Python日期时间处理 Python日期时间处理:一种更简单的方式 日期和时间处理是许多程序中必不可少的部分。Python提供了一个标准库来处理日期和时间,这个库叫做datetime,它提供了一些类来处理不同的日期和时间格式…

SpringCloud --- Nacos注册中心、配置管理

一、Nacos注册中心 1.1、认识和安装Nacos Nacos是阿里巴巴的产品,现在是SpringCloud中的一个组件。相比Eureka功能更加丰富,在国内受欢迎程度较高。 1.2、服务注册到nacos Nacos是SpringCloudAlibaba的组件,而SpringCloudAlibaba也遵循Spr…

基于U-Net系列的医学图像分割

U-Net 在FCN 的基础上增加了上采样操作的次数和跳跃连接,使用跳跃连接将解码器的输出特征与编码器的语义特征融合,提高了分割精度,改善了 FCN 上采样不足的问题。 U-Net中没有全连接层,通过互连卷积与反卷积过程中的特征&#xff…

前端优化的分析

前端优化的分析 目录概述需求: 设计思路实现思路分析渲染层性能更好的API 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy,skip hardness,make a better result,wait for change,cha…

在线问诊小程序系统方案以及价值

方案价值zlzwgz0127 1.扩大医院流量 a.预约到院 在线展示专家的介绍,更能彰显实力,吸引患者来院就医, 用户可选择在线问诊和预约到院 b.社区团购导流 与我们合作社区团购给医院的体检产品导流 c.专家直播导流 通过专家直播吸引潜在患者…