【代码随想录】刷题Day3

news2024/12/25 23:43:36

1.链表删除

203. 移除链表元素

循环删除

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        if(head==nullptr)
            return head;
        ListNode* prev=nullptr;
        ListNode* cur=head;
        while(cur)
        {
            if(prev==nullptr&&cur->val==val)
            {
                ListNode* tmp = cur;
                cur=cur->next;
                head=cur;
                delete tmp;
            }
            else if(cur->val==val)
            {
                ListNode* tmp = cur;
                prev->next=cur->next;
                cur=cur->next;
                delete tmp;
            }
            else
            {
                prev=cur;
                cur=cur->next;
            }
        }
        return head;
    }
};

1.如果head节点是空,没有继续的必要了,直接返回

2.删除某个节点的链表是需要其前驱的,因为我们要关联起该节点的前后位置,后面的节点next存储,但是前驱没有啊;以至于我们需要一个prev节点,在下一次循环前将prev指向现在的节点,这样下一次cur的前驱就有了

3.如果是head节点要删除,一定要更新head的位置,我在题中判断的方式是prev是否为空作为cur指向的是否是head的位置

4.当然删除节点要记得释放空间哦~

要逆转一下思维

这个链表的形式不就是单支的二叉树嘛,关键是删除节点还得知道这个节点的前驱,我们可不可以从后往前递归删除啊, 这样我们已经走过上一层,在要删除的位置其实已经可以知道前驱了,那么从后往前的思路应该行得通欸

递归删除

class Solution {
public:
    void _removeR(ListNode*& head,ListNode* cur, ListNode* prev,int& val)
    {
        if(cur==nullptr)
        {
            return;
        }
        _removeR(head,cur->next,cur,val);
        if(cur->val==val)
        {
            ListNode* tmp = cur;
            if(prev==nullptr)
                head=cur->next;
            else
                prev->next=cur->next;
            cur=cur->next;
            delete tmp;
        }
        return;
    }

    ListNode* removeElements(ListNode* head, int val) {
        _removeR(head,head,nullptr,val);
        return head;
    }
};

1.首先如果对链表的递归删除不熟,我们把他可以看成是单支的二叉树,只需要递归一个分支就行了

2.设置cur,prev,val;这里不加引用,因为我们的cur和prev每一层都会更新

3.到底端的判断是cur的指向是否为nullptr

4.我们先要走到最后,所以是先递归后处理,再返回的

5.删除的思想和循环一致

6.要注意的是,我是传了head,并且是引用的;这是因为可能我们的头节点要更新,如果不写头节点位置删除了,头节点也丢失了,所以参数返回了一个head

7.那么要更新head节点的条件也很简单,只要prev的指向是空就行,那么更新head=cur->next,完成所有处理条件

8.处理完要返回上层

2.恼人的链表构造

707. 设计链表

没什么好说的,注意前提条件就行

class MyLinkedList {
public:
    struct Listnode
    {
        int val;
        struct Listnode* next;
        Listnode(int val)
        :val(val),next(nullptr)
        {}
    };

    MyLinkedList() {
        head=new Listnode(0); //头节点
        _size=0;
    }
    
    int get(int index) {
        if (index > (_size - 1) || index < 0) 
            return -1;
        Listnode* cur = head->next;
        while(index--)
        {
            cur = cur->next;
        }
        return cur->val;
    }
    
    void addAtHead(int val) {
        Listnode* newNode = new Listnode(val);
        newNode->next = head->next;
        head->next = newNode;
        _size++;
    }
    
    void addAtTail(int val) {
        Listnode* newNode = new Listnode(val);
        Listnode* cur = head;
        while(cur->next)
        {
            cur=cur->next;
        }
        cur->next=newNode;
        _size++;
    }
    
    void addAtIndex(int index, int val) {
        if(index > _size) return;
        if(index < 0) index = 0;  
        Listnode* newNode = new Listnode(val);
        Listnode* cur = head;
        while(index--)
        {
            cur=cur->next;
        }
        newNode->next=cur->next;
        cur->next=newNode;
        _size++;
    }
    
    void deleteAtIndex(int index) {
        if (index >= _size || index < 0) 
            return;
        Listnode* cur = head;
        while(index--)
        {
            cur=cur->next;
        }
        Listnode* tmp = cur->next;
        cur->next=cur->next->next;
        delete tmp;
        _size--;
    }
private:
    Listnode* head;
    int _size;
};

3.反转链表

206. 反转链表

三指针反转

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* prev = nullptr;
        ListNode* cur = head;
        if(cur==nullptr)
            return head;
        ListNode* next = head->next;
        if(next==nullptr)
            return head;
        while(next)
        {
            cur->next=prev;
            prev=cur;
            cur=next;
            next=next->next;
        }
        cur->next=prev;
        head=cur;
        return head;
    }
};

1.由于是三个指针,prev先指向nullptr,cur指向head,next指向head的next;不过之中有一些判断,不然会出现非法访问

prev优先指向nullptr,没有什么条件的

cur指向head,如果head为空,下面的执行都无意义了,那就直接返回head就行

next指向head的next,如果next为空,只有一个节点,也不需要反转,所有也返回head就行

2.之后循环看的都是next是否为空,之所以不是判断next的下一个为空,是因为我们要尽可能反转多个节点,这样最后剩下的操作会更少

3.到这一步就是在循环中,到底是先执行还是先往后走,我们认为是先执行,执行cur的下一个,由于知道prev,所以cur指向prev就行,再更新所有往后一位即可

4.到这里就是循环结束了,此时next执行空了,但是cur还有值,所以一定要将cur的下一个指向prev,当然我们要返回的是head,以至于我们把head也更新成cur就可以了

依然逆转一下思维

我们根据第一题知道其实递归可很简单的得到前驱,所以递归在这题仍然适用 

递归反转

class Solution {
public:
    void _reverseR(ListNode*& head,ListNode* cur,ListNode* prev)
    {
        if(cur->next==nullptr)
        {
            head=cur;
            head->next=prev;
            return;
        }
        _reverseR(head,cur->next,cur);
        cur->next=prev;
        return;
    }

    ListNode* reverseList(ListNode* head) {
        if(head==nullptr||head->next==nullptr)
            return head;
        _reverseR(head,head,nullptr);
        return head;
    }
};

1.在递归外先判断一些不适合进入到递归的形式,比如头节点为空,链表只有一个这些形式

2.递归内,到末端的条件判断,就是cur的next是否为空,因为我们要更新头节点的位置,所以不能是cur为空;更新head,head的next也要更新指向prev

3.先递归到底端,所以先递归再执行反转

4.反转的思路就更加简单了,只要把cur的next指向prev就行,随后返回上层

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

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

相关文章

对项目总体把控不足,项目经理应该怎么办?

公司现状&#xff1a;项目人员紧缺&#xff0c;只有两人了解此项目技术细节&#xff0c;其中一个不常驻现场&#xff0c;另一个是执行项目经理李伟。 项目经理王博是公司元老&#xff0c;同时负责多个项目&#xff0c;工作比较忙&#xff0c;不常驻现场&#xff0c;没有参加过…

【Web服务】HTTP和DNS重要知识

304状态码 HTTP状态码中的304状态码表示"未修改"&#xff0c;通常在客户端发起了一个带有If-Modified-Since头部的GET请求时会得到这个响应。服务器通过比较If-Modified-Since头部指定的时间戳和资源的最后修改时间来判断资源是否被修改过&#xff0c;如果没有修改则…

Vue(十七):利用 html2canvas、JsPDF 依赖实现打印功能

效果 主程序 <!-- 打印区域 --> <el-container ref"PdfPage"><!-- 过滤打印按钮 --><el-button type"primary" data-html2canvas-ignoretrue click"printPage">打印</el-button><el-main><!-- 滚动区域…

AI绘画——Three Delicacy Wonton (三餡馄饨Mix)模型

目录 怎么做三鲜馄饨Mix&#xff1a; 描述&#xff1a; 版本&#xff1a; 使用说明&#xff1a; 实操演示&#xff08;多图预警&#xff09; Picture One Picture Two Picture Three 怎么做三鲜馄饨Mix&#xff1a; 切一点金弘道 &#xff08;https://civitai.com/mo…

无人机遥感影像应用

目录 一、无人机遥感技术 二、无人机遥感影像数据生产 三、无人机遥感影像应用 一、无人机遥感技术 1.无人机遥感系统组成 1.1无人机遥感系统组成—无人机平台 1.2无人机遥感系统组成—传感器 2.无人机遥感技术的特点 高时效性&#xff1a;准确并快速获取地表数据 高分辨率…

加密算法在链接防抓取和数据防篡改应用

写在前 对工作中遇到的加密算法算法进行总结和思考&#xff0c;分析不同加密算法优缺点和对应解决问题场景&#xff0c;思考进一步可改进点。 场景1、加密算法在链接防止抓取中应用 客户端和服务器端对(appverisionurl盐offset)使用加密规则进行加密&#xff0c;对传输数据进…

bing搜索技巧

“” 双引号表示完全匹配&#xff0c;结果中必须出现与搜索文本完全相同的内容。 2 A -B 搜索包含A但不包含B的结果&#xff08;请注意A后面的空格不能省略&#xff09; 3 filetype 搜索对应类型的文件。例如&#xff1a;中国防火墙 filetype:ppt&#xff0c;即为搜索包含主题…

Hive概论、架构和基本操作

Hive是一个构建在Hadoop上的数据仓库框架&#xff0c;最初&#xff0c;Hive是由Facebook开发&#xff0c;后台移交由Apache软件基金会开发&#xff0c;并做为一个Apache开源项目。 Hive是基于Hadoop的一个数据仓库工具&#xff0c;可以将结构化的数据文件映射为一张数据库表&a…

【Maven 入门】第三章、Maven POM

一、什么是 Maven POM&#xff1f; POM 是 Maven 中最重要的概念之一&#xff0c;它描述了一个 Maven 项目的基本信息和依赖关系。简单来说&#xff0c;POM 就是一个 XML 文件&#xff0c;其中包含了以下内容&#xff1a; 项目的基本信息&#xff0c;如名称、版本号、描述等。…

超详细Redis入门教程——Redis 的安装与配置

前言 本文小新为大家带来 超详细Redis入门教程——Redis 的安装与配置 相关知识&#xff0c;具体内容包括Redis 的安装&#xff0c;连接前的配置&#xff0c;Redis 客户端分类&#xff08;包括&#xff1a;命令行客户端&#xff0c;图形界面客户端&#xff0c;Java 代码客户端&…

政策和技术引导企业布局光伏组件回收市场 积极应对光伏组件“退役潮”

一、发展光伏组件回收是实现我国碳中和的战略需求 光伏组件回收主要是通过对其各组件部分进行物理或化学方法处理&#xff0c;进而得到拥有经济价值的材料&#xff0c;进而减少环境污染&#xff0c;实现对废弃光伏组件资源的回收再利用。 我国是光伏组件制造及应用大国&#…

远程仓库的克隆和上传

要创建项目文件夹下打开Git Bush Here --> git clone 远程仓库地址 ! 没有权限访问 原因: 之前登过别人邮箱号,导致克隆失败 解决: 第一步. C盘->用户->电脑用户名->.gitconfig->用vscode打开删除信息,然后保存即可 . 第二步.电脑搜索找到 凭据管理器->wi…

【Python_Scrapy学习笔记(十一)】基于Scrapy框架的下载器中间件添加Cookie参数

基于Scrapy框架的下载器中间件添加Cookie参数 前言 本文中介绍 如何基于 Scrapy 框架的下载器中间件添加 Cookie 参数。 正文 1、添加中间件的流程 在 middlewares.py 中新建 Cookie参数 中间件类在 settings.py 中添加此下载器中间件&#xff0c;设置优先级并开启 2、基…

【C++初阶】命名空间 namespace

一.前言 在正式进入C前&#xff0c;我们需要先了解了解C。顾名思义&#xff0c;C是基于C的一种编程语言&#xff0c;相较于C&#xff0c;C写出来的代码更简洁&#xff0c;有时候C需要几百行代码&#xff0c;而C只需要几十行就可以解决&#xff0c;C也很好的解决了C中存在的一些…

【夜莺监控搭建】

夜莺监控搭建V6版本 v6版本系统架构安装部署安装时序数据库安装mysql、redis和n9e&#xff08;夜莺主程序&#xff09;安装categraf 登录平台如何修改密码添加数据源 官网&#xff1a; https://flashcat.cloud/ GitHub项目地址&#xff1a; https://github.com/ccfos/nightin…

Mongo集群化部署+高可用架构

数据库开发系列 文章目录 数据库开发系列前言一、MongoDB存储引擎二、MongoDB 复制&#xff08;副本集&#xff09;三、为什么需要分片集群架构四、高可用分片集群架构&#xff08;复制集&#xff09;总结 前言 数据库的演进 随着计算机的发展&#xff0c;越来越多的数据需要被…

python+vue 服装穿搭信息管理系统

本系统采用自上往下的方法开发&#xff0c;基本定位如下功能&#xff1a; 本课题要求实现一套服装信息管理系统的设计与实现&#xff0c;系统主要包括管理员模块和用户模块功能模块。 由于本系统需要在不同设备上都能运行&#xff0c;而且电脑配置要求也要越低越好&#xff0c…

SpringMVC框架详解(学习总结)

目录 什么是MVC SpringMVC概述 SpringMVC常见开发方式 SpringMVC执行流程 SpringMVC核心组件介绍 快速构建Spring MVC程序 SpringMVC参数绑定 SpringMVC跳转方式 SpringMVC处理json请求和响应 SpringMVC静态资源处理 SpringMVC操作session和cookie SpringMVC拦截器 …

基于nuxt3的语雀文档批量导出

语雀文档批量导出 快速访问 Github Blog 项目由来 语雀是一个不错的笔记与文档知识库&#xff0c;但是最近发现他开始割韭菜了&#xff0c; 知识库的公开开始收费&#xff0c;就想着把内容都导出自己来部署&#xff0c;发现并没有批量操作&#xff0c;amazing&#xff0c;…

美国运营商PTCRB认证PTCRB认证怎么做PTCRB认证是什么?

大家好&#xff0c;今天我想和大家分享一下什么是PTCRB认证&#xff01; PTCRB是指个人通信服务型号认证评估委员会&#xff0c;由北美移动运营商于1997年成立。目前的运营商已经不仅限于北美&#xff0c;而是涵括全球范围内的移动运营商成员。其目的是为包括Cellular GERAN&a…