【代码随想录】刷题Day5

news2024/9/21 16:09:53

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;
    }
};

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

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

相关文章

C语言之详解静态变量static

在C语言中static是用来修饰变量和函数的,这篇文章详细介绍了static主要作用,文章中有详细的代码实例,需要的朋友可以参考阅读 在C语言中: static是用来修饰变量和函数的 static主要作用为: 1. 修饰局部变量 - 静态局部变量 2. …

linux软件安装指令---yum和rpm

这里写目录标题 一 yum指令1. yum install 软件名2. yum remove 软件名3 检查已经安装成功的软件 二 rpm指令1 rpm -q2 rpm -qa|less3 rpm -qa| grep python4 搜索文件的详细信息5 查询一个rpm中的包安装到哪里去了6 查询一个文件属于那个包7 软件包的卸载 三 总结四 示范安装 …

【面试系列】四种经典限流算法讲解

固定窗口限流算法 介绍 固定窗口限流算法(Fixed Window Rate Limiting Algorithm)是一种最简单的限流算法,其原理是在固定时间窗口(单位时间)内限制请求的数量。该算法将时间分成固定的窗口,并在每个窗口内限制请求的数量。具体来…

锦江展焕新演绎,憬黎公寓住造理想

2023年4月19-21日,“万物春生,赴锦程”锦江酒店(中国区)投资加盟品鉴会,在上海世博展览馆完美收官。这是一场迎着酒店行业复苏浪潮的年度盛会。 插图丨锦江酒店(中国区) 作为锦江酒店&#xff…

60 openEuler 22.03-LTS 搭建MySQL数据库服务器-安装、运行和卸载

文章目录 60 openEuler 22.03-LTS 搭建MySQL数据库服务器-安装、运行和卸载60.1 安装60.2 运行60.3 卸载 60 openEuler 22.03-LTS 搭建MySQL数据库服务器-安装、运行和卸载 60.1 安装 配置本地yum源,详细信息请参考《openEuler 22.03-LTS 搭建repo服务器》。 清除…

JavaWeb01(WEB环境的搭建)

目录 一.JDK 1.1 JDK是什么? 1.2 如何下载和安装jdk? 1.3 如何配置环境变量? 1.4 如何测试java环境变量是否配置成功? 二.Tomcat 2.1 Tomcat是什么? 2.2 为什么需要使用它? 2.3 如何下载? 2.4 了解Tomcat目录结构 2.5 如何修改Tomcat端口号(0-65535) 2.6 如何使…

Nginx的优化及防盗链

Nginx程序优化 模块 ngx_http_access_module模块 访问模块 ngx_http_auth_basic_module模块 用户访问控制 ngx_http_stub_status_module模块 查看http状态统计模块 ngx_http_gzip_module模块 压缩模块 ngx_http_ssl_module模块 设置http的连接模块 ngx_http_rewrite_mod…

Python selenium 模块使用find_element_by_id无效

一、发生异常: 二、原因 查询安装selenium的版本是4.5.0 这个版本不支持页面对象的定位find_element_by_id方法,以前版本支持这些进行元素定位: find_element_by_id find_element_by_name find_element_by_xpath find_element_by_link_text find_elem…

找工作半年,四月成功拿到华为offer,分享一波面经...

前言 不论是校招还是社招都避免不了各种⾯试、笔试,如何去准备这些东⻄就显得格外重要。不论是笔试还是⾯试都是有章可循的,我这个“有章可循”说的意思只是说应对技术⾯试是可以提前准备,所谓不打无准备的仗就是这个道理。 以下为大家&…

【李宏毅】Bert家族

课程资料来自李宏毅老师油土鳖频道的BERT家族教程:上,下。 这两章主要是如何在pre-train的模型上做fine-turn,如何利用大模型来做自己的task。 目录 前言 什么是预训练 What is pre-train model 如何微调 How to fine-tune 入参 出参 …

[架构之路-174]-《软考-系统分析师》-5-数据库系统-7-数据仓库技术与数据挖掘技术

5 . 7 数据仓库技术 数据仓库是一个面向主题的、集成的、相对稳定的、反映历史变化的数据集合,用于支持管理决策。近年来,人们对数据仓库技术的关注程度越来越尚,其原因是过去的几十年中,建设了无数的应用系统,积累了…

5G 智慧教育解决方案(ppt可编辑)

本资料来源公开网络,仅供个人学习,请勿商用,如有侵权请联系删除 5G智慧教育-系统架构图 教学-远程互动教学系统架构图 平安校园-整体系统架构 平安校园:安全管理 平安校园-安全管理 视频监控 统一接入 统一管理 应急联动 系统通…

设计模式:结构型模式 - 代理模式

文章目录 1.概述2.结构3.静态代理4.JDK动态代理5.CGLIB动态代理6.三种代理的对比7.优缺点8.使用场景 1.概述 由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象…

DataX-阿里开源离线同步工具在Windows上实现Sqlserver到Mysql全量同步和增量同步

场景 Kettle-开源的ETL工具集-实现SqlServer到Mysql表的数据同步并部署在Windows服务器上: Kettle-开源的ETL工具集-实现SqlServer到Mysql表的数据同步并部署在Windows服务器上_etl实现sqlserver报表服务器_霸道流氓气质的博客-CSDN博客 上面讲过Kettle的使用&am…

2.19 信号概述

1.信号的概念 1.1 信号的概念 信号是 Linux 进程间通信的最古老的方式之一,是事件发生时对进程的通知机制,有时也 称之为软件中断,它是在软件层次上对中断机制的一种模拟,是一种异步通信的方式。信号 可以导致一个正在运行的进程…

【Prompt使用场景】

Prompt使用场景 场景1:问答问题(技巧1)场景2:基于示例回答(技巧2)场景3:推理场景4:无中生有——写代码(技巧3)场景5:锦上添花——改写内容(技巧4)场景6:锦上添花——信息解释场景7:化繁为简——信息总结(技巧5)场景8:化繁为简——信息提取(技巧6)场景1:问…

化工厂5G+蓝牙+LoRa室内人员定位系统解决方案

随着化工行业的不断发展,化工厂的生产和管理工作变得越来越复杂和繁琐。人员定位成为一项重要的任务,尤其是在化工厂室内,为了确保员工的安全和提高工作效率,需要实现对人员的快速准确定位。因此,化工厂室内人员定位系…

催收公司承信科技申请纳斯达克IPO上市,募资1500万美元

来源:猛兽财经 作者:猛兽财经 猛兽财经获悉,来自苏州的催收公司,承信信息科技有限公司(下称“承信科技”)近期已向美国证券交易委员会(SEC)提交招股书,申请在纳斯达克I…

vue yarn npm

2016年左右 ,facebook针对npm包管理工具存在的性能问题进行了针对性开发并发布了yarn新的node包开发管理工具,具体对比,同学们自行网上搜索资料对比。 配置 1、先下载好NodeJS,然后输入如下命令安装yarn npm install -g yarn 2、…

【并发基础】一篇文章带你彻底搞懂Java线程中断的底层原理——interrupt()、interrupted()、isInterrupted()

目录 〇、Java线程中断与阻塞的区别 0.1 线程中断 0.2 线程阻塞 一、线程的中断 二、中断方法 2.1 void interrupt() 2.1.1 可中断的阻塞 2.1.2 不可中断的阻塞 2.1.3 实践案例 2.2 boolean isInterrupted() 2.3 boolean interrupted() 2.4 代码案例 三、源码分析…