【面试经典 150 | 链表】删除链表的倒数第 N 个结点

embedded/2024/9/24 17:29:58/

文章目录

  • 写在前面
  • Tag
  • 题目来源
  • 解题思路
    • 方法一:统计节点个数
    • 方法二:双指针
  • 写在最后

写在前面

本专栏专注于分析与讲解【面试经典150】算法,两到三天更新一篇文章,欢迎催更……

专栏内容以分析题目为主,并附带一些对于本题涉及到的数据结构等内容进行回顾与总结,文章结构大致如下,部分内容会有增删:

  • Tag:介绍本题牵涉到的知识点、数据结构;
  • 题目来源:贴上题目的链接,方便大家查找题目并完成练习;
  • 题目解读:复述题目(确保自己真的理解题目意思),并强调一些题目重点信息;
  • 解题思路:介绍一些解题思路,每种解题思路包括思路讲解、实现代码以及复杂度分析;
  • 知识回忆:针对今天介绍的题目中的重点内容、数据结构进行回顾总结。

Tag

链表-删除节点】【迭代


题目来源

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


解题思路

方法一:统计节点个数

思路

一种朴素的方法是首先统计链表中节点的个数 m,倒数第 n 个节点就是正数第 m - n + 1 个节点。我们从头结点开始,找到正数第 m - 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:const int getLength(ListNode* head) {int len = 0;while (head) {++len;head = head->next;}return len;}ListNode* removeNthFromEnd(ListNode* head, int n) {ListNode* dummy = new ListNode(0, head);int m = getLength(head);ListNode* cur = dummy;for (int i= 0; i < m - n; ++i) {cur = cur->next;}cur->next = cur->next->next;return dummy->next;}
};

复杂度分析

时间复杂度: O ( m ) O(m) O(m) m m m 为链表的长度。

空间复杂度: O ( 1 ) O(1) O(1)

方法二:双指针

思路

我们先用一个指针指向链表的第 n 个节点,此时增加另一个指针指向头结点,接着让两个指针同时向链表尾部移动,每一移动一个位置,当第一个指针到达 nullptr 时,我们也就找到了需要删除的节点。

如果我们利用 代码 中的 while 循环就找到了要删除节点的上一个节点,此时直接将该节点的指针指向下下个节点即可。

代码

/*** 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) {ListNode *first = head;ListNode *dummy = new ListNode(0, head);ListNode *second = dummy;for(int i = 0; i < n; ++i)first = first->next;while(first){first = first->next;second = second->next;}second->next = second->next->next;return dummy->next;}
};

复杂度分析

时间复杂度: O ( m ) O(m) O(m) m m m 为链表的长度。

空间复杂度: O ( 1 ) O(1) O(1)


写在最后

如果您发现文章有任何错误或者对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。

如果大家有更优的时间、空间复杂度的方法,欢迎评论区交流。

最后,感谢您的阅读,如果有所收获的话可以给我点一个 👍 哦。


http://www.ppmy.cn/embedded/9688.html

相关文章

C++程序设计(第四版郑莉)-------第五章

数据的共享与保护 5.1 标识符的作用域与可见性 5.1.1作用域 &#xff1a;一个标识符在程序正文中有效的区域 1函数原型作用域&#xff08;最小的作用域&#xff09; &#xff1a;在函数原型声明时形参的作用范围 2局部作用域 &#xff1a;函数参数从声明到}结束 3类的作…

在 PyCharm 中使用系统安装的 Python 和 Anaconda 的 Python什么区别

virtualenv environment &#xff1a; virtualenv 是一个用于创建独立 Python 环境的工具。它可以在同一个系统上创建多个相互独立的 Python 环境&#xff0c;每个环境都有自己的 Python 解释器和包库&#xff0c;从而可以实现不同项目之间的依赖隔离和版本控制。coda environm…

0基础如何进入IT行业?

1、零基础者想要进入IT行业&#xff0c;可以选择以下学习路径&#xff1a; 首先&#xff0c;理解IT行业的基础概念和知识体系是非常必要的。这包括计算机组成原理&#xff0c;如存储程序、冯诺依曼机器的结构、指令和流水线等&#xff1b;计算机网络&#xff0c;如分组交换和电…

Linux网络编程--网络传输

Linux网络编程--网络传输 Linux网络编程TCP/IP网络模型网络通信的过程局域网通信跨网络通信&#xff1a;问题总结&#xff1a; Linux网络编程 TCP/IP网络模型 发送方&#xff08;包装&#xff09;&#xff1a; 应用层&#xff1a;HTTP HTTPS SSH等 —> 包含数据&#xff0…

我独自升级崛起怎么下载 一文分享我独自升级崛起游戏下载教程

我独自升级崛起怎么下载 一文分享我独自升级崛起游戏下载教程 我独自升级&#xff1a;崛起是一款由韩国漫画改编而成的热门多人网络在线联机游戏&#xff0c;这款游戏是一款的角色扮演类型游戏&#xff0c;游戏有着独一无二的剧情模式。小伙伴们在游戏中可以体验到独特的成长系…

2024.4.21周报

目录 摘要 Abstract 文献阅读&#xff1a;Next Item Recommendation with Self-Attentive Metric Learning 问题及方法 论文贡献 方法论 序列感知的推荐系统 神经注意模型 模型&#xff1a;ATTREC 序列推荐 基于Self-Attention的用户短期兴趣建模 用户长期兴趣建模…

Day4 商品管理

Day4 商品管理 这里会总结构建项目过程中遇到的问题&#xff0c;以及一些个人思考&#xff01;&#xff01; 学习方法&#xff1a; 1 github源码 文档 官网 2 内容复现 &#xff0c;实际操作 项目源码同步更新到github 欢迎大家star~ 后期会更新并上传前端项目 编写品牌服务 …

mysql基础7——where与having的差异

where直接对表中的字段进行限定 筛选结果 having需要根据分组关键字group by一起使用&#xff0c;通过对分组字段和分组计算函数限定 筛选结果 distinct 字段 &#xff0c; 返回字段中所有不同的值 distinct 字段; where 如果需要对关联表进行查询&#xff0c;where字段执…