算法刷题-链表

news2024/12/21 19:07:17

算法刷题-链表

203. 移除链表元素

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点

示例 1:

img

输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]

思路

建立一个虚拟头节点,指向链表的头节点,然后再遍历链表删除值为val的节点,这样比较好方便删除头节点

代码

    ListNode* removeElements(ListNode* head, int val) {
        ListNode* head2 =new ListNode(0);
        head2->next=head;
        ListNode* cur=head2;
        while(cur->next!=NULL){
            if(cur->next->val==val){
                ListNode* tmp=cur->next;
                cur->next=tmp->next;
                delete tmp;
            }else{
                cur=cur->next;
            }
        }
        head=head2->next;
        delete head2;
        return head;
    }

707. 设计链表

你可以选择使用单链表或者双链表,设计并实现自己的链表。

单链表中的节点应该具备两个属性:valnextval 是当前节点的值,next 是指向下一个节点的指针/引用。

如果是双向链表,则还需要属性 prev 以指示链表中的上一个节点。假设链表中的所有节点下标从 0 开始。

实现 MyLinkedList 类:

  • MyLinkedList() 初始化 MyLinkedList 对象。
  • int get(int index) 获取链表中下标为 index 的节点的值。如果下标无效,则返回 -1
  • void addAtHead(int val) 将一个值为 val 的节点插入到链表中第一个元素之前。在插入完成后,新节点会成为链表的第一个节点。
  • void addAtTail(int val) 将一个值为 val 的节点追加到链表中作为链表的最后一个元素。
  • void addAtIndex(int index, int val) 将一个值为 val 的节点插入到链表中下标为 index 的节点之前。如果 index 等于链表的长度,那么该节点会被追加到链表的末尾。如果 index 比长度更大,该节点将 不会插入 到链表中。
  • void deleteAtIndex(int index) 如果下标有效,则删除链表中下标为 index 的节点。

思路

注意野指针

代码

class MyLinkedList {
public:
    struct node {
        int val;
        node *next;

        node(int x) : val(x), next(nullptr) {}
    };

    MyLinkedList() {
        sz = 0;
        head = new node(0);
    }

    int get(int index) {
        node *cur = head->next;
        if (index < 0 || index >= sz) return -1;
        while (index--) cur = cur->next;
        return cur->val;
    }

    void addAtHead(int val) {
        addAtIndex(0, val);
    }

    void addAtTail(int val) {
        addAtIndex(sz, val);
    }

    void addAtIndex(int index, int val) {
        if (index > sz)return;
        if (index < 0) index = 0;
        node *cur = head;
        while (index-- > 0) cur = cur->next;
        node *tmp = new node(val);
        tmp->next = cur->next;
        cur->next = tmp;
        sz++;
    }

    void deleteAtIndex(int index) {
        if (index < 0 || index >= sz)return;
        node *cur = head;
        while (index--) cur = cur->next;
        node *tmp = cur->next;
        cur->next = tmp->next;
        delete tmp;
        tmp = nullptr;//防止野指针
        sz--;
    }

private:
    int sz;
    node *head;
};

206. 反转链表

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例 1:

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

思路

让每个节点指向前面的节点即可

代码

    ListNode* reverseList(ListNode* head) {
        ListNode* right;
        ListNode* cur=head;
        ListNode* pre=nullptr;
        while(cur){
            right=cur->next;
            cur->next=pre;
            pre=cur;
            cur=right;
        }
        return  pre;
    }

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

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。

示例 1:

输入:head = [1,2,3,4]
输出:[2,1,4,3]

思路

参考代码随想录中的反转步骤,还是用到虚拟头节点:

代码

    ListNode *swapPairs(ListNode *head) {
        ListNode *dummyHead = new ListNode(0);
        dummyHead->next = head;
        ListNode *cur = dummyHead;
        while (cur->next != nullptr && cur->next->next != nullptr) {
            ListNode *node1 = cur->next;
            ListNode *node2 = node1->next;
            ListNode *node3 = node2->next;
            cur->next = node2;
            node2->next = node1;
            node1->next = node3;
            cur = node1;
        }
        return dummyHead->next;
    }

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

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

示例 1:

输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]

思路

双指针,让快指针先走n+1步,然后慢指针从头节点开始和快指针一起走,

当快指针走到最后的时候,此时慢指针的下一个节点就是倒数第N个节点,删除即可

代码

    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* dummy =new ListNode(0);
        dummy->next=head;
        ListNode* fast= dummy;
        ListNode* slow =dummy;
        n++;
        while(n--) fast=fast->next;
        while(fast!=nullptr) fast=fast->next,slow=slow->next;
        ListNode* tmp=slow->next;
        slow->next=tmp->next;
        delete tmp;
        return dummy->next;
    }

面试题 02.07. 链表相交

给你两个单链表的头节点 headAheadB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null

图示两个链表在节点 c1 开始相交**:**

img

题目数据 保证 整个链式结构中不存在环。

注意,函数返回结果后,链表必须 保持其原始结构

思路

因为相交肯定是从最后一个开始香蕉

先计算两个链表的长度,然后让链表长度长的先把多出来的部分走完,再一起往前走,知道相同为止

代码

    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        int n=0,m=0;
        ListNode *dummy=headA;
        while(dummy!=nullptr) n++,dummy=dummy->next;
        dummy=headB;
        while(dummy!=nullptr) m++,dummy=dummy->next;
        ListNode* curA=headA;
        ListNode* curB=headB;
        if(m>n) swap(curA,curB),swap(n,m);
        while(n>m) curA=curA->next,n--;
        while(curA!=nullptr){
            if(curA==curB) return curA;
            curA=curA->next,curB=curB->next;
        }
        return nullptr;
    }

142. 环形链表 II

给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos-1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

不允许修改 链表。

示例 1:

输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。

思路

代码随想录:

相遇时:

slow指针走了 x + y x+y x+y

fast指针走了 x + y + n ( y + z ) x+y+n(y+z) x+y+n(y+z)

因此: 2 ( x + y ) = x + y + n ( y + z ) 2(x+y)=x+y+n(y+z) 2(x+y)=x+y+n(y+z)

化简得: x = n ( y + z ) − y x=n(y+z)-y x=n(y+z)y

整理得: x = ( n − 1 ) ( y − z ) + z x=(n-1)(y-z)+z x=(n1)(yz)+z

n = 1 n=1 n=1的时候, x = z x=z x=z

也就是说:从相遇点和头节点开始同时走,他们第一次相遇的时候就是环形的入口。

代码

    ListNode *detectCycle(ListNode *head) {
        ListNode *fast=head;
        ListNode *slow=head;
        while(fast!=nullptr &&fast->next!=nullptr){
            slow=slow->next;
            fast=fast->next->next;
            if(slow==fast){
                ListNode *a=head;
                ListNode *b=fast;
                while(a!=b) a=a->next,b=b->next;
                return a;
            }
        }
        return nullptr;
    }

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

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

相关文章

小成代码路的错误

文章目录 计算长度使用左闭右开的方法getline(解决输入空格问题和给一个输入的界限&#xff09;stoi(字符串转整形&#xff09;stoi&#xff08;整型转字符串型&#xff09;reverse&#xff08;反转函数&#xff09;将字符串立志静成员变量在类外初始化&#xff1b;但是有特例&…

FreeSWITCH 1.10.10 简单图形化界面12 - 注册IMS

FreeSWITCH 1.10.10 简单图形化界面12 - 注册IMS 0、 界面预览1、IMS注册-SIP中继基本设置界面2、IMS注册-SIP中继呼叫设置3、IMS中继-代理设置界面4、IMS注册-SIP中继状态界面5、IMS注册-SIP中继详细状态界面6、IMS注册-SIP中继代拨号码优先界面 FreeSWITCH界面安装参考&#…

Qt planeGame day10

Qt planeGame day10 Game基本框架 qt中没有现成的游戏框架可以用&#xff0c;我们需要自己搭框架首先创建一个QGame类作为框架&#xff0c;这个基本框架里面应该有如下功能&#xff1a;游戏初始化 void init(const QSize& siez,const QString& title);游戏反初始化(…

系统报错“由于找不到vcomp140.dll无法继续执行代码”的解决方案

在我们日常使用电脑的过程中&#xff0c;可能会遇到一些错误提示&#xff0c;其中之一就是“找不到vcomp140.dll”。这个错误可能让许多用户感到困扰&#xff0c;因为它可能影响到我们的电脑使用。那么&#xff0c;vcomp140.dll是什么意思&#xff1f;当我们遇到这个问题时&…

学习笔记2——Nosql

学习笔记系列开头惯例发布一些寻亲消息 链接&#xff1a;https://baobeihuijia.com/bbhj/contents/3/194205.html 跟学链接 跟学视频链接&#xff1a;https://www.bilibili.com/video/BV1S54y1R7SB/?spm_id_from333.999.0.0 &#xff08;建议有java基础的同学学习或者一直…

发挥设计模式单例模式的力量:从技术到社会的转变

文章目录 &#x1f31f; 如何将设计模式单例模式运用到社会当中&#x1f34a; 什么是单例模式&#x1f34a; 单例模式在现实生活中的应用&#x1f389; 数据库连接池&#x1f389; 日志管理器&#x1f389; 系统配置中心 &#x1f34a; 如何将单例模式应用于社会中&#x1f389…

【Unity程序技巧】公共Update管理器

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

hugo-stack for github

静态博客框架jekyll、hexo和hugo三者之间的区别与差异 博客生成器? 全名为静态网站生成器&#xff0c; 可在任意拥有主机功能的环境下寄存(托管)可直接配合域名进行全球访问 劣势: 每次更新网页必须重新生成整个网站编译速度&#xff08;单位&#xff1a;秒&#xff09; Jek…

Win下Eclipse安装

eclipse官网https://www.eclipse.org/downloads/ 软件介绍&#xff1a; Eclipse 是一个开放源代码的、基于 Java 的可扩展开发平台。Eclipse 是 Java 的集成开发环境&#xff08;IDE&#xff09;&#xff0c;当然 Eclipse 也可以作为其他开发语言的集成开发环境&#xff0c;如…

为什么使用KT6368A蓝牙芯片用app连接,基本都在5分钟左右后断开

为什么我们自己的板子用KT6368A蓝牙芯片&#xff0c;用app连接&#xff0c;基本都是在5分钟左右后 断掉或者断开&#xff0c;什么原因。参考的原理图&#xff0c;是官方的图纸如下 遇到这样的问题&#xff0c;根据我们的经验&#xff0c;大概率是硬件问题&#xff0c;分析方法如…

深度好文:How to get started in C++!

Datawhale干货 作者&#xff1a;zclll&#xff0c;推荐&#xff1a;卢雨畋&#xff0c;Datawhale成员 在大家的不懈催更下&#xff08;hhh)&#xff0c;这篇文章终于和大家见面了。对于程序设计、软件开发而言&#xff0c;我都只是一个入门水平而已&#xff08;也许C略多一点&…

whatsapp的越狱特征检测

一、检测点 1、检测目录 opendir打开bin是否成功 2、检测模块 解析macho的header头获取加载的模块&#xff0c;获取进程的所有模块&#xff0c;判断是否包含如下模块&#xff1a;substrate,watusi,zdumper 3、检测文件 判定文件或是应用是否的路径是否存在 /Applications/Cydia…

单链表的相关操作(精简版..在修改中)

目录 前言&#xff1a; 哨兵位&#xff1a; 链表的概念 链表的相关操作&#xff1a; 链表的创建&#xff1a; 打印链表&#xff1a; 申请新节点&#xff1a; 链表的尾插&#xff1a; &#xff01;&#xff01;&#xff01;对于传参中二级指针的解释&#xff1a; 链表的…

[C国演义] 第十六章

第十六章 等差数列的划分最长递增子序列 等差数列的划分 力扣链接 子数组 ⇒ dp[i]的含义: yinums[i] 为结尾的所有子数组中的 等差数列数组最多的个数子数组⇒ 状态转移方程: 根据最后一个元素的构成 初始化: 涉及到 i-1, i-2 ⇒ 所以要初始化dp[0] 和 dp[1] 都初始化为 0…

一次不成功的抓包过程

想搞Android app抓包&#xff0c;简单的方法&#xff0c;已经不起作用&#xff0c;打开charles代理工具&#xff0c;抓不到我的目标app任何请求&#xff0c;搞了两三天&#xff0c;也没成功。 我的目标APP里&#xff0c;经过apk反编译出来&#xff0c;看到有libflutter.so文件&…

AM@导数的应用@二阶导数的应用@函数的性态研究@函数图形的绘制

文章目录 概念称呼说明驻点极值和极值点最值极值点和最值比较曲线的凹凸性凹凸性判定定理&#x1f47a;例证明 凹凸性和单调性无必然关系拐点寻找拐点&#x1f47a; 函数图形的绘制例 概念 本文讨论导数的应用:利用导数研究函数的性态相关定理主要通过Lagrange中值定理进行推导…

首篇大模型压缩论文综述

首篇大模型压缩综述来啦&#xff01;&#xff01;&#xff01; 来自中国科学院和人民大学的研究者们深入探讨了基于LLM的模型压缩研究进展并发表了该领域的首篇综述《A Survey on Model Compression for Large Language Models》。 Abstract 大型语言模型&#xff08;LLMs&a…

文件操作 IO

文件(File) 狭义的文件: 指的是硬盘上的文件和目录 广义的文件: 泛指计算机中很多软硬件资源(操作系统中把很多硬件和软件资源抽象成了文件, 按照文件的方式同意管理) 本章内容只讨论狭义的文件 路径 绝对路径: 以c: , d: 盘符开头的路径相对路径: 以当前所在的目录为基准(…

【问题思考总结】如何求椭圆的切线?【过椭圆外一点】

问题 今天做2009年数一的真题&#xff0c;发现第17题求切线十分难顶&#xff0c;我用的方法是切线和椭圆方程联立&#xff0c;还有切线斜率和椭圆上一点和远点斜率相乘等于-1的方法。 思考 经过思考后&#xff0c;我认为之前的那个属于是高中方法&#xff08;还不完全是&…

Prometheus接入AlterManager配置邮件告警(基于K8S环境部署)

文章目录 一、配置AlterManager告警发送至邮箱二、Prometheus接入AlterManager配置三、部署PrometheusAlterManager(放到一个Pod中)四、测试告警 注意&#xff1a;请基于 PrometheusGrafana监控K8S集群(基于K8S环境部署)文章之上做本次实验。 一、配置AlterManager告警发送至邮…