代码随想录2刷|链表1.链表理论基础2移除链表元素3.设计链表4.翻转链表5.两两交换链表中的节点6.删除链表的倒数第N个节点7.链表相交8.环形链表lI

news2024/12/23 4:31:22

2移除链表元素

链接:力扣

 一刷:

/**
 * 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 *L=new ListNode(-1);
        L->next=head;

        ListNode *slow=L,*fast=head,*r=L;

        while(fast!=nullptr)
        {
            if(fast->val==val)
            {
                slow->next=fast->next;
                fast=slow->next;
            }
            else{
                fast=fast->next;
                slow=slow->next;
            }
        }
        return L->next;



    }
};

跟一刷写法不太一样,一开始忘记slow->next=nullptr报错

/**
 * 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 *L=new ListNode(-1);
        L->next=head;
        ListNode *slow=L,*fast=L->next;
        if(head==nullptr)
        {
            return head;
        }
        while(fast!=nullptr)
        {
            if(fast->val==val)
            {
                fast=fast->next;
            }
            else
            {
                slow->next=fast;
                slow=slow->next;
                fast=fast->next;

            }
        }
        slow->next=nullptr;
        return L->next;

    }
};

707. 设计链表 

链接:力扣

 

二刷感觉比一刷理解的更深刻了。

期间用了尾指针,但是发现hold不住。只能尾插时从头开始找到尾再插入。

另外其实一些函数有出错,所以另外写了print函数,每一步都打印链表进行调试。

巧用了while(p!=nullptr && index) ,每次想着index=0,index=1进行写

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

};

    MyLinkedList() {//构造函数,初始化头节点
     //初始化头节点
        L=new ListNode(-1);
       // r=L;//尾指针

    }

    void print_L(ListNode *L)
    {
        ListNode *p=L->next;
        while(p!=nullptr)
        {
            cout<<p->val<<"  ";
            p=p->next;
        }
        cout<<endl;
    }
    
    int get(int index) {
        ListNode *p=L->next;
        while(p!=nullptr && index)
        {
            p=p->next;
            index--;
        }
        if(p!=nullptr)
        {
            return p->val;
        }
       // print_L(L);
        return -1;

    }
    
    void addAtHead(int val) {//头插法
        ListNode *temp=new ListNode(val);
        temp->next=L->next;
        L->next=temp;
       // print_L(L);
    }
    
    void addAtTail(int val) {//尾插法
        ListNode *temp=new ListNode(val);
        ListNode *r=L;
        while(r->next!=nullptr)
        {
            r=r->next;
        }
        r->next=temp;
        //print_L(L);
    }
    
    void addAtIndex(int index, int val) {
        //假设index=0,=1
        ListNode *p=L;
        ListNode *temp=new ListNode(val);
        //将一个值为 val 的节点插入到链表中下标为 index 的节点之前
        while(p!=nullptr && index)
        {
            p=p->next;
            index--;
        }
        if(p!=nullptr)//如果 index 比长度更大,该节点将 不会插入 到链表中
        {
            temp->next=p->next;
            p->next=temp;
        }
        //print_L(L);
        
    }
    
    void deleteAtIndex(int index) {
        //如果要删除节点,首先节点要存在
        ListNode *pre=L;
        while(pre!=nullptr && index)
        {
            pre=pre->next;
            index--;
        }
        if(pre==nullptr)
        {
            //没有什么好删的
        }
        else if(pre!=nullptr && pre->next==nullptr)
        {
            //没有什么好删的
        }
        else
        {
            pre->next=pre->next->next;
        }
       // print_L(L);

    }
    private:
        ListNode *L=nullptr;//L为头节点
       // ListNode *r=nullptr; 不太好掌握,废了



};

/**
 * 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);
 */

206.反转链表 

链接:力扣

  二刷还是各种报错,最主要的是忘记了一刷的简便算法

二刷的错误点在于边界判断太多了,而且一开始的慢指针尾巴忘记指向空指针,导致整个链表没有尾巴,一直报错了十分钟。

/**
 * 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 || head->next==nullptr)
        {
            return head;
        }

        ListNode *slow=head;
        //忘记写slow->next==nullptr,导致反转后的链表没有尾巴
        ListNode *fast=head->next;
         slow->next=nullptr;
        while(fast!=nullptr && fast->next!=nullptr)
        {
            ListNode *temp=fast;
            fast=fast->next;
            temp->next=slow;
            slow=temp;
        }
        if(fast!=nullptr)
        {
            fast->next=slow;
            return fast;
        }
        return  head;
        
    }
};

回忆一刷的简单做法,直接让slow指针从空开始,fast从head开始.

/**
 * 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 *slow=nullptr,*fast=head;
        while(fast!=nullptr)
        {
            ListNode *temp=fast;
            fast=fast->next;
            temp->next=slow;
            slow=temp;
        }
        return slow;


    }
};

24. 两两交换链表中的节点 

链接:力扣

 基本还是搞错了,cur 和 temp temp1 三个指针 四个节点,相隔距离,链接关系,都是需要稍微死记硬背一点的。

/**
 * 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 {
    /*再看一遍我也只是跟着过一遍。
   重点 cur temp temp1 三个指针交叉成一个均匀的麻花,涉及四个节点,三个指针分别指向1、2、4节点
   
   最后cur=temp,每次前进一步

   */

public:
    ListNode* swapPairs(ListNode* head) {
        if(head==nullptr || head->next==nullptr)//只有0个或者1个节点
        {
            return head;
        }
        //两个及以上节点,可以交换
        ListNode *L=new ListNode(-1);
        L->next=head;
        ListNode *cur=L,*temp=nullptr,*temp1=nullptr;
        while(cur!=nullptr && cur->next!=nullptr && cur->next->next!=nullptr)
        {
            temp=cur->next;
            temp1=cur->next->next->next;

            cur->next=temp->next;
            cur->next->next=temp;
            temp->next=temp1;

            cur=temp;//每次只前进一步!!这里一开始写成了temp1
        }
        return L->next;
        


    }
};

 19. 删除链表的倒数第 N 个结点

链接:力扣

 十分尴尬,我已经忘了最佳的那种做法。。。。就是快慢指针那种。

对链表遍历了两遍。

二刷做法:

/**
 * 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* removeNthFromEnd(ListNode* head, int n) {
        //以第一个为例,删除倒数第2个节点,就是找倒数第三个节点==正数第三个节点,链表长度为5.意思是找到第len-n个节点即可

        //第一步,创建头节点
        ListNode *L=new ListNode(-1);
        L->next=head;

        //第二步,计算整个链表长度
        ListNode *p=L->next;
        int len=0;
        while(p!=nullptr)
        {
            len++;
            p=p->next;
        }
       
        int k=len-n;
        p=L;//这一步很重要!一定要搞清楚!!
        while(p!=nullptr && k)
        {
            p=p->next;
            k--;
        }
        if(p!=nullptr && p->next!=nullptr)
        {
            p->next=p->next->next;
        }
        return L->next;

    }
};

一刷,快慢指针最佳做法,重新写一遍.注意n++。fast和slow都从空的头节点开始,fast要先走n+1步

/**
 * 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 {
    /*
    以第一个为例,删除链表的倒数第2个节点相当于找到正数第三个节点
                               3                    2
                               n                    len-n
    让fast指针先走n步,然后slow再和fast一起走
    */
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        if(head==nullptr )
        {
            return head;
        }
        ListNode *L=new ListNode(-1);
        L->next=head;
        ListNode *fast=L,*slow=L;
        n++;
        while(n && fast!=nullptr)
        {
             fast=fast->next;
             n--;
        }
        
       

        while(fast!=nullptr)
        {
            slow=slow->next;
            fast=fast->next;
        }
         
        if(slow!=nullptr && slow->next!=nullptr)
        {
            slow->next=slow->next->next;
        }
        return L->next;

    }
};

面试题 02.07. 链表相交 

链接:力扣

 挺好的,看了以前写的那一遍,然后重写了一遍。只能说对于资质普通者,要重复刷题才行。

p1 、p2第一次遍历完后要从恢复到链表头开始遍历

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode *p1=headA,*p2=headB;
        int lenA=0,lenB=0;
        while(p1!=nullptr)
        {
            p1=p1->next;
            lenA++;
        }

         while(p2!=nullptr)
        {
            p2=p2->next;
            lenB++;
        }
        int len=lenA-lenB;
        // cout<<lenA<<"    "<<lenB<<"  "<<len<<endl;

        //重新从头开始遍历
        p1=headA,p2=headB;
        if(lenA>=lenB)
        {
            while(len && p1!=nullptr)
            {
                p1=p1->next;
               // cout<<"p1    "<<p1->val<<endl;
                len--;
            }

        }
        else
        {
            len=-len;
             while(len && p2!=nullptr)
            {
                p2=p2->next;
                len--;
            }
        }
        while(p1!=nullptr && p2!=nullptr && p1!=p2)
            {
                p1=p1->next;
                p2=p2->next;
            }
            return p2;
        
        
    }
};

142. 环形链表 II

链接:力扣

 二刷发现思路记错了,fast一次走两步,slow一次走一步,我记成fast多走两步后,两个就同步了。确实如果fast只是先多走两步,那毫无意义,fast和slow永远差两步永远不会相交!!

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
 /*
 有一道题印象深刻,判断两个链表相交的位置。突然发现是这道题!真尴尬
 基本思路:
 先让fast节点多走两步,!!fast指针是一步走两个节点,slow指针一步走一个节点
 然后fast和slow必然在环内相交。记住环内相交节点,然后让第三个指针从链表起始节点出发,相交节点指针和起始指针同步出发,来到环的入口节点
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        if(head==nullptr || head->next==nullptr)
        {
            return nullptr;
        }
        ListNode *fast=head,*slow=head;
        while(fast!=nullptr && fast->next!=nullptr)
        { 
            slow=slow->next;
            fast=fast->next->next;
            if(slow==fast)//说明有环
            {
               //cout<<"有环"<<endl;
                ListNode *p=head;
                while(p!=slow)
                {
                    p=p->next;
                    slow=slow->next;
                }
                return slow;

            }
        }
        return nullptr;
        
        
    }
};

 

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

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

相关文章

Vue中如何进行地理位置搜索与地点选择

Vue中如何进行地理位置搜索与地点选择 随着移动互联网和定位技术的普及&#xff0c;地理位置搜索和地点选择成为了很多应用程序中必不可少的功能。在Vue中&#xff0c;我们可以使用一些开源的地图API和第三方组件来实现这些功能。本文将介绍如何在Vue中进行地理位置搜索和地点…

【北邮国院大三下】Logistics and Supply Chain Management 物流与供应链管理 Week3

北邮国院大三电商在读&#xff0c;随课程进行整理知识点。仅整理PPT中相对重要的知识点&#xff0c;内容驳杂并不做期末突击复习用。个人认为相对不重要的细小的知识点不列在其中。如有错误请指出。转载请注明出处&#xff0c;祝您学习愉快。 如需要pdf格式的文件请私信联系或…

gradlew test 失败

前言 在idea内执行./gradlew test&#xff0c;发现如下报错&#xff1a; Could not initialize class org.codehaus.groovy.runtime.InvokerHelper 分析 google了一堆&#xff0c;说要用groovy&#xff0c;可是我没有用groovy&#xff0c;以前也是正常启动的。后来无意发现&a…

游戏玩家的新大陆?小红书游戏内容场景洞察

2023年&#xff0c;如果你问年轻人他们在哪里讨论游戏&#xff1f;他们可能会提到一些平台&#xff0c;比如Steam、TapTap、B站、微博或者论坛。但是如果你向身边的女孩子询问&#xff0c;她们可能会惊喜地告诉你&#xff1a;小红书。 小红书平台一直给人的标签是是“美妆、旅…

UWB高精度实时定位系统源码(springboot+vue)

一、系统概况 UWB&#xff08;Ultra-wideband&#xff09;技术是一种无线载波通讯技术&#xff0c;它不采用正弦载波&#xff0c;而是利用纳秒级的非正弦波窄脉冲传输数据&#xff0c;因此其所占的频谱范围很宽。自主研发&#xff0c;最高定位精度可达10cm&#xff0c;具有高精…

数据库架构是否该随着公司估值一起变化?

原文&#xff5c;The growing pains of database architecture 作者&#xff5c;Tim Liang, Software Engineer at Figma 2020 年&#xff0c;因为 Figma 不断加入新功能&#xff0c;筹备第二条产品线和用户不断增长导致数据库流量每年以 3x 速度增长&#xff0c;我们的基础设…

将数组中指定位置的元素替换为指定值np.put()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 将数组中指定位置的元素替换为指定值 np.put() 选择题 下列说法错误的是? import numpy as np a np.array([1, 2, 3]) print("【显示】a ", a) print("【执行】np.put(arr…

Spring Boot进阶(47):Spring Boot之集成Cache缓存 | 超级详细,建议收藏

1. 前言 今天&#xff0c;我们来聊聊缓存这个话题。身为开发者肯定都知道&#xff0c;程序的瓶颈绝大体现在于数据库方面&#xff0c;而内存读取远远快于硬盘&#xff0c;当并发上升到一定高度&#xff0c;一次又一次的重复请求数据导致大量时间耗费在数据库查询上&#xff0c;…

win10搭建hmailserver邮件服务器(hmailserver+phpstudy+roundcube)

环境安装&#xff1a;Mysqlhmailserverphpstudyroundcube 一、Mysql安装 官网下载链接&#xff1a;https://www.mysql.com/ zip安装包下载链接&#xff1a;https://dev.mysql.com/downloads/mysql/ 1、zip安装包安装 &#xff08;1&#xff09;下载合适版本的mysql zip包&…

LeetCode------ 相交链表

前言 &#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;推荐专栏: &#x1f354;&#x1f35f;&#x1f32f;C语言进阶 &#x1f511;个人信条: &#x1f335;知行合一 &#x1f349;栏目介绍:<<刷题集>>用于记录,力扣,牛客等刷题网站上的刷…

EasyExcel 批量导出

文章目录 前言一、EasyExcel 导出封装二、食用步骤1.自定义excel样式2.导出数据 三、复杂excel导出3.1. 自定义复杂表头2. 多sheet 前言 上篇写了数据导入&#xff0c;本文补充一下EasyExcel 批量导出 包括常规excel和复杂excel 一、EasyExcel 导出封装 import com.alibaba.…

手把手教你如何解开安装UKUI的黑屏故障

手把手教你如何解开安装UKUI的黑屏故障 引子 作为一个不折腾不舒服斯基的Linuxer&#xff0c;我又开始安装配置开放欧拉操作系统了。这是国产自主安全可控的Linux发行版。欧拉发行版Linux的发起者就是干正经事的华为&#xff0c;比其它拉大旗扯虎皮的国产Linux低调务实多了。…

远程控制之原理和实战

按理来说&#xff0c;本人不该发表此类专业文章&#xff0c;鄙人零星碎片化的开发经历&#xff0c;让本人斗胆向诸位网友&#xff0c;在远控方面做一点演示说明&#xff0c;谈论一点自己的认识。 程序工程代码地址&#xff1a;点击此处下载。 程序分为两个部分&#xff0c;控…

(三)Kafka 生产者

文章目录 1. Kafka 发送消息的主要步骤2.创建 Kafka 生产者3.发送消息到 Kafka&#xff08;1&#xff09;发送并忘记&#xff08;2&#xff09;同步发送&#xff08;3&#xff09;异步发送 4.生产者配置&#xff08;1&#xff09;client.id&#xff08;2&#xff09;ack&#x…

查看P端日志操作步骤

1.登录PUTTY,这里以联调环境103.160.139.82为例。 2.登录&#xff0c;查看用户名&#xff1a;hxb或zzkpt,密码&#xff1a;用户名01动态口令。 例如hxb, sunmenglei01888888 3.进入P端日志存放目录&#xff0c; cd /home/zzkpt/logs/bcip 4.比如我要查看2023年5月5日&#xf…

索引常见问题

被问到SQL和索引优化问题&#xff0c;如何切入&#xff1f; 可以用 explain 进行分析 思考流程&#xff1a;找到哪些运行时间长浪费性能的sql&#xff0c;然后再用explain分析 慢查询日志 MySQL可以设置慢查询日志&#xff0c;当SQL执行的时间超过我们设定的时间&#xff0…

在UE中使用SVT(VirtualTexture)功能

前几年VT技术非常的火&#xff0c;这项技术主要运用在地形上&#xff0c;可以达到更高级别的精细度和更多次数的纹理混合&#xff0c;但实际非地形也可以用&#xff0c;特别是对于贴图尺寸比较大且多维度子材质比较多的模型&#xff0c;做了材质合并以及VT优化后&#xff0c;可…

二、线性神经网络

文章目录 前言一、线性回归1. 线性回归的基本元素1.1 线性模型1.2 损失函数1.3 解析解1.4 梯度下降1.5 用模型进行预测 2. 正态分布与平方损失3. 从线性回归到深度网络 二、线性回归的代码实现1. 生成数据集2. 读取数据集2.1 手动实现读取数据集2.2 简洁实现读取数据集 3. 初始…

便携补光LED化妆镜方案

近段时间&#xff0c;现代科技的衍生产品&#xff0c;智能化妆镜很受爱美女士的喜爱。为此&#xff0c;宇凡微推出无极调光的LED化妆镜方案。主控芯片采用宇凡微YF单片机&#xff0c;根据LED化妆镜方案的不同功能&#xff0c;支持定制开发。 一、LED化妆镜方案介绍 在日常过程中…

Html span标签的详细介绍

HTML &#xff1c;span&#xff1e;标签_span标签_allway2的博客-CSDN博客 一、span标签的定义及用法 在html中&#xff0c;span标签是使用来组合文档中的行内元素&#xff0c;以便使用样式来对它们进行格式化。 span标签本身并没有什么格式表现&#xff08;比如&#xff1a;换…