代码随想录day3 203.移除列表元素 707.设计链表 206.反转链表

数组是在内存中是连续分布的,但是链表在内存中可不是连续分布的。

双链表

单链表中的指针域只能指向节点的下一个节点。

双链表:每一个节点有两个指针域,一个指向下一个节点,一个指向上一个节点。

双链表 既可以向前查询也可以向后查询。

问题:约瑟夫环是什么?循环列表为什么能解决约瑟夫环的问题?

链表的代码:

// 单链表
struct ListNode {
    int val;  // 节点上存储的元素
    ListNode *next;  // 指向下一个节点的指针
    ListNode(int x) : val(x), next(NULL) {}  // 节点的构造函数
};

删除链表节点,对于c++需要释放内存,其他语言例如Java、Python,就有自己的内存回收机制,就不用自己手动释放了。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        ListNode* virt=new ListNode(0,head);  //要加new
        virt->val=0;
        virt->next=head;
        ListNode* tmp;
        tmp=virt;
        while(tmp->next!=NULL){
            
            if(tmp->next->val==val){
                ListNode* tmp1= tmp->next;
                // tmp->next =tmp1->next;
                // tmp1->next=NULL;
                tmp->next=tmp->next->next;

                delete tmp1;
            }
            else{
                tmp=tmp->next;
            }
        }
        head=virt->next;
        delete virt;
        return head; //必须从头节点返回才行,直接选取head节点开始返回不行
    }
};

参考了题解才改对的,就是主要是本来没有 head=virt->next;        delete virt; 就直接返回head,可能因为有前他指针指向head,不能直接返回。要->next得到虚拟节点的下一个。

另外,是用ListNode* virt=new ListNode(0,head); ,也就是用new什么来声明一个指针。

delete tmp1;就是指针节点。

707.设计链表  

链表操作的两种方式:

  1. 直接使用原来的链表来进行操作。
  2. 设置一个虚拟头结点在进行操作。

这道题需要自己定义链表节点结构体

MyLinkedList()是初始化函数

class MyLinkedList {
public:
    struct linkedNode{
        int val;
        linkedNode* next;
        linkedNode(int val):val(val),next(nullptr){}
    };
    MyLinkedList() {
        // int num=0;
        // linkedNode * head=new linkedNode(0);
        _num=0;
        _head=new linkedNode(0);
        

    }
    
    int get(int index) {
        
        if(_num<=index) return -1;
        linkedNode * tmp=_head;int tmpN=-1;
        while(tmp->next!=NULL){
            tmp=tmp->next;
            tmpN++;
            if(tmpN==index){
                return tmp->val;
            }
        }
        return -1;

    }
    
    void addAtHead(int val) {
        // linkedNode * tmp=head;
        linkedNode * newT=new linkedNode(val);
        newT->next=_head->next;
        _head->next=newT;
        _num++;
    
        
    }
    
    void addAtTail(int val) {
            linkedNode * newT=new linkedNode(val);
            linkedNode * tmp=_head;//int tmpN=-1;
        while(tmp->next!=NULL){
            tmp=tmp->next;
            
        }
        _num++;
        tmp->next=newT;

    }
    
    void addAtIndex(int index, int val) {
        if(index>_num) return ;
        linkedNode * newT=new linkedNode(val);
            linkedNode * tmp=_head;int tmpN=-1;
        while(tmp->next!=NULL){
            
            tmpN++;
            if(tmpN==index){
                newT->next=tmp->next;
                _num++;
                tmp->next=newT;
                return;
                // return tmp->val;
            }
            tmp=tmp->next;
        }
        if((tmpN+1)==index){
            tmp->next=newT;
            _num++;
        }
        return ;
        // tmp->next=newT;
    }
    
    void deleteAtIndex(int index) {
        
            linkedNode * tmp=_head;int tmpN=-1;
        while(tmp->next!=NULL){
            
            tmpN++;
            if(tmpN==index){
                linkedNode * tmpN=tmp->next;
                tmp->next=tmp->next->next;
                delete tmpN;
                _num--;
    
                return;
                // return tmp->val;
            }
            tmp=tmp->next;
        }
    }
    private:
    int _num;
    linkedNode * _head;
};

/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList* obj = new MyLinkedList();
 * int param_1 = obj->get(index);
 * obj->addAtHead(val);
 * obj->addAtTail(val);
 * obj->addAtIndex(index,val);
 * obj->deleteAtIndex(index);
 */

这道题需要自己再定义一个linkedNode结构体,一开始我不知道linkednode是不是应该放在mylinkedlist下面,mylinkedlist是初始化函数,所以是放在public下。而初始化函数是赋值初值的,在private:下面可以声明函数的私有成员变量,而不是在初始化函数声明。看了眼题解的写法才写出来,主要是忘记了c++的语法。

要注意index小于0时特判不合法。下面代码是复制过来的,为了提示自己tmp最好赋值个nullptr。

 void deleteAtIndex(int index) {
        if (index >= _size || index < 0) {
            return;
        }
        LinkedNode* cur = _dummyHead;
        while(index--) {
            cur = cur ->next;
        }
        LinkedNode* tmp = cur->next;
        cur->next = cur->next->next;
        delete tmp;
        //delete命令指示释放了tmp指针原本所指的那部分内存,
        //被delete后的指针tmp的值(地址)并非就是NULL,而是随机值。也就是被delete后,
        //如果不再加上一句tmp=nullptr,tmp会成为乱指的野指针
        //如果之后的程序不小心使用了tmp,会指向难以预想的内存空间
        tmp=nullptr;
        _size--;
    }

 

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(head==nullptr) return nullptr;
            ListNode * tmp =head;
            ListNode * tmpN;
            tmpN= tmp->next;
            ListNode* node;
            while(tmpN!=NULL){
                node=tmpN;
                tmpN=tmpN->next;
                node->next=tmp;
                tmp=node;
                // tmp=tmp->next;
            }
            head->next=NULL;
        return tmp;
    }
};

一遍ac,注意特判空列表的情况。比如有三个节点,第二个节点反过来要指向第一个,那原本遍历数组需要的第二个节点指向的下一个也要用其他指针指向保留。其实套用在具体例子下就比较好写了。相当于一个三个数的滑窗,每次窗口内要处理前两个数为后一个数指向前一个数。

        其实就是双指针法,题解的方法是:

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* temp; // 保存cur的下一个节点
        ListNode* cur = head;
        ListNode* pre = NULL;
        while(cur) {
            temp = cur->next;  // 保存一下 cur的下一个节点,因为接下来要改变cur->next
            cur->next = pre; // 翻转操作
            // 更新pre 和 cur指针
            pre = cur;
            cur = temp;
        }
        return pre;
    }
};

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

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

相关文章

vcomp140.dll是什么意思?vcomp140.dll缺失怎么修复的五个方法

在电脑使用过程中&#xff0c;我们常常会遇到一些错误提示&#xff0c;其中之一就是“由于找不到vcomp140.dll无法继续执行代码”。这个错误提示通常出现在运行某些程序时&#xff0c;给使用者带来了很大的困扰。那么&#xff0c;为什么会出现这个错误呢&#xff1f;又该如何解…

借助ChatGPT帮助程序员解决系统线上问题

对不同的业务以及不同的中间件提问题的方式不同 首先我们在每一种类型的提问前都需要对AI进行定义也就是让AI明白你提问的问题是那个行业的那个技术 定义身份话术 常见的 #接下来的对话你将以一名java高级开发工程师的身份和我聊天 接下来的对话你将以一名XXXX的身份和我聊天提…

关于Typora如何插入自己的云端视频的方法

关于Typora如何插入自己的云端视频的方法 文章目录 关于Typora如何插入自己的云端视频的方法前言&#xff1a;实现步骤&#xff1a;小结 前言&#xff1a; 我本来使用gitee来作为typora的图床&#xff0c;但我现在想要把我自己的视频上传到云端&#xff0c;然后通过超链接在ty…

Programming Contest 2023(AtCoder Beginner Contest 331)D题 Tile Pattern --- 题解

目录 D - Tile Pattern 题目大意&#xff1a; 思路&#xff1a; 代码&#xff1a; D - Tile Pattern D - Tile Pattern (atcoder.jp) 题目大意&#xff1a; 给你一个n和q&#xff0c;n为局部棋盘大小(n*n) 并且给出局部棋盘中黑白子位置的放置情况&#xff0c;q为查询次数…

java的四种内部类,从0讲清楚

什么是内部类&#xff1f; 为什么要学习内部类&#xff1f; 可以发现&#xff0c;发动机虽然跟汽车相关&#xff0c;但发动机不像车龄或颜色一样&#xff0c;只用一个变量就可以描述&#xff0c;而是要有发动机品牌&#xff0c;发动机年限&#xff0c;多个变量描述发动机。那么…

从“芯”到云,看亚马逊云科技如何让未来“平等”发生

文章目录 业界最全面算力选择&#xff0c;有效解决多样性需求多年自研芯片积累&#xff0c;带来性能与性价比双重优势全球基础设施与独特的业务模式&#xff0c;让创新不受限 “科幻作家威廉吉布森说‘未来已至&#xff0c;只是还没有均匀分布’。”2023年6月底&#xff0c;当亚…

【开源存储】minio对象存储部署实践

文章目录 一、前言1、介绍说明2、部署方式3、冗余模式4、约束限制4.1、规格参数4.2、API支持a、minio不支持的Amazon S3 Bucket APIb、minio不支持的Amazon S3 Object API 二、部署说明1、软件安装2、minio单机部署3、minio分布式部署3.1、前置条件3.2、开始运行3.3、操作说明 …

Linux 进程(三)

Linux进程状态的查看&#xff1a; 这是Linux内核源代码对于进程状态的定义&#xff1a; R运行状态&#xff08;running&#xff09;: 并不意味着进程一定在运行中&#xff0c;它表明进程要么是在运行中要么在运行队列里。 S睡眠状态&#xff08;sleeping): 意味着进程在…

ipvlan介绍

最近使用docker&#xff0c;涉及到需要跨多台物理机部署系统&#xff0c;查了好多资料&#xff0c;最后查到了ipvlan。那什么是vlan&#xff0c;什么又是ipvlan。 交换机层面的vlan&#xff0c;是按802.1Q规范&#xff0c;在链路层中加了4字节的标识vlan的数据&#xff0c;交换…

如何在WordPress中批量替换图片路径?

很多站长在使用WordPress博客或者搬家时&#xff0c;需要把WordPress文章中的图片路径进行替换来解决图片不显示的问题。总结一下WordPress图片路径批量替换的过程&#xff0c;方便有此类需求的站长们学习。 什么情况下批量替换图片路径 1、更换了网站域名 有许多网站建设初期…

灯光开不了了,是不是NVIDIA的问题

如果你跟我一样灯光亮度调节不了了&#xff0c;然后显示适配器又没有了&#xff0c;你看一下是不是和我这个大怨种一样把NVIDIA卸了&#xff0c;为了这个东西&#xff0c;这屏幕亮瞎我的眼镜&#x1f622;&#x1f622;。只需要进入官网&#xff0c;你就可以直接找到&#xff0…

SSM框架(五):Maven进阶

文章目录 一、分模块开发1.1 分模块开发的意义1.2 步骤 二、依赖管理2.1 依赖传递2.2 可选依赖和排除依赖 三、继承与聚合3.1 聚合3.2 继承3.3 聚合和继承区别 四、属性4.1 pom文件的依赖使用属性4.2 资源文件使用属性 五、多环境开发六、跳过测试七、私服7.1 下载与使用7.2 私…

前端面试灵魂提问(1)

1.自我介绍 2.在实习中&#xff0c;你负责那一模块 3.any与unknow的异同 相同点&#xff1a;any和unkonwn 可以接受任何值 不同点&#xff1a;any会丢掉类型限制&#xff0c;可以用any 类型的变量随意做任何事情。unknown 变量会强制执行类型检查&#xff0c;所以在使用一个…

Redis RDB

基于内存的 Redis, 数据都是存储在内存中的。 那么如果重启的话, 数据就会丢失。 为了解决这个问题, Redis 提供了 2 种数据持久化的方案: RDB 和 AOF。 RDB 是 Redis 默认的持久化方案。当满足一定条件的时候, 会把当前内存中的数据写入磁盘, 生成一个快照文件 dump.rdb。Redi…

各类声音数据集大合集—乐器、车辆、鸟鸣、蜜蜂声音、歌曲、喇叭、人类声音不同等类型的声音数据集

最近收集了一大波关于各类声音的数据集&#xff0c;包含乐器、车辆、鸟鸣、蜜蜂声音、歌曲、喇叭、人类声音不同等类型的声音数据集&#xff0c;废话不多说&#xff0c;给大家逐一介绍&#xff01;&#xff01; 1、吉他和弦大调、小调数据集 吉他和弦大调、小调数据集&#x…

Hive数据倾斜之:数据类型不一致导致的笛卡尔积

Hive数据倾斜之&#xff1a;数据类型不一致导致的笛卡尔积 目录 Hive数据倾斜之&#xff1a;数据类型不一致导致的笛卡尔积一、问题描述二、原因分析三、精度损失四、问题解决 一、问题描述 如果两张表的jion&#xff0c;关联键分布较均匀&#xff0c;没有明显的热点问题&…

无桌面版docker在Ubuntu系统上安装

目录 注意 系统要求 卸载旧版本 安装 使用apt存储库安装 1. 设置 Docker 的apt存储库。 2. 安装Docker软件包 3. 通过运行镜像来验证Docker Engine安装是否成功 hello-world。 从包中安装 1. 进入 https://download.docker.com/linux/ubuntu/dists/。 2. 在列表中选择…

阿里云MySQL从 2003->1251->1396

目的 由于需要在阿里云的实例中装MySQL数据库&#xff0c;安装前期&#xff08;本地访问&#xff09;还是挺顺利的&#xff0c;但是到了远程连接的时候&#xff0c;却出现了一系列的Bug&#xff0c;以为是没有 实名认证没有备案 的原因导致的&#xff0c;但是后来…

在Spring Boot中使用@Async实现一个异步调用

在使用异步注解之前&#xff0c;我们需要先了解&#xff0c;什么是异步调用&#xff1f; 异步调用对应的事同步调用&#xff0c;同步调用是值程序按照我们定义的顺序依次执行&#xff0c;每一行程序都必须等待上一行的程序执行完成之后才执行&#xff0c;而异步是指在顺序执行…

动态规划------方法汇总

核心&#xff1a; 状态定义 状态转移方程 启发思路&#xff08;两种情况&#xff09;&#xff1a;选 或 不选 / 选哪个 DP三步&#xff1a;先写回溯&#xff0c;时间复杂度 指数级别&#xff1b;递归的过程中会重复计算&#xff0c;要保存计算结果&#xff0c;递归搜索…