LeetCode_19_中等_删除链表的倒数第N个结点

news/2024/10/17 22:30:02/

文章目录

  • 1. 题目
  • 2. 思路及代码实现(Python)
    • 2.1 计算链表长度
    • 2.2 栈


1. 题目

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

示例 1:

输入: h e a d = [ 1 , 2 , 3 , 4 , 5 ] , n = 2 head = [1,2,3,4,5], n = 2 head=[1,2,3,4,5],n=2
输出: [ 1 , 2 , 3 , 5 ] [1,2,3,5] [1,2,3,5]

示例 2:

输入: h e a d = [ 1 ] , n = 1 head = [1], n = 1 head=[1],n=1
输出: [ ] [ ] []

示例 3:

输入: h e a d = [ 1 , 2 ] , n = 1 head = [1,2], n = 1 head=[1,2],n=1
输出: [ 1 ] [1] [1]


提示

  • 1 < = s z < = 30 1 <= sz <= 30 1<=sz<=30,其中 s z sz sz 为链表中的节点数目
  • 0 < = N o d e . v a l < = 100 0 <= Node.val <= 100 0<=Node.val<=100
  • 1 < = n < = s z 1 <= n <= sz 1<=n<=sz

2. 思路及代码实现(Python)

在对链表进行操作时,一种常用的技巧是添加一个哑节点(dummy node),它的 next \textit{next} next 指针指向链表的头节点。这样一来,就不需要对头节点进行特殊的判断了。

例如,在本题中,如果我们要删除节点 y y y,我们需要知道节点 y y y 的前驱节点 x x x,并将 x x x 的指针指向 y y y 的后继节点。但由于头节点不存在前驱节点,因此我们需要在删除头节点时进行特殊判断。但如果我们添加了哑节点,那么头节点的前驱节点就是哑节点本身,此时我们就只需要考虑通用的情况即可。

题解引用来源:力扣官方题解

2.1 计算链表长度

一种容易想到的方法是,我们首先从头节点开始对链表进行一次遍历,得到链表的长度 L L L。随后我们再从头节点开始对链表进行一次遍历,当遍历到第 L − n + 1 L−n+1 Ln+1 个节点时,它就是我们需要删除的节点。

为了方便删除操作,我们可以从哑节点开始遍历 L − n + 1 L−n+1 Ln+1 个节点。当遍历到第 L − n + 1 L−n+1 Ln+1 个节点时,它的下一个节点就是我们需要删除的节点,这样我们只需要修改一次指针,就能完成删除操作。

在这里插入图片描述
该算法的时间复杂度为 O ( L ) O(L) O(L),其中, L L L 是链表的长度;空间复杂度为 O ( 1 ) O(1) O(1)

class Solution:def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:def getLength(head: ListNode) -> int:length = 0while head:length += 1head = head.nextreturn lengthdummy = ListNode(0, head)length = getLength(head)cur = dummyfor i in range(1, length - n + 1):cur = cur.nextcur.next = cur.next.nextreturn dummy.next

执行用时:44 ms
消耗内存:16.45 MB

2.2 栈

我们也可以在遍历链表的同时将所有节点依次入栈。根据栈「先进后出」的原则,我们弹出栈的第 n n n 个节点就是需要删除的节点,并且目前栈顶的节点就是待删除节点的前驱节点。这样一来,删除操作就变得十分方便了。

上一个方法用链表结构,存储每个节点的指向节点,因此节省存储空间,无需存储所有的节点。而用栈的方法,在Python中用元素带顺序的列表来表征进出操作,实现逻辑很直观简单,但需牺牲部分存储空间。

该算法的时间复杂度为 O ( L ) O(L) O(L),空间复杂度也为 O ( L ) O(L) O(L)

class Solution:def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:dummy = ListNode(0, head)stack = list()cur = dummywhile cur:stack.append(cur)cur = cur.nextfor i in range(n):stack.pop()prev = stack[-1]prev.next = prev.next.nextreturn dummy.next

执行用时:27 ms
消耗内存:16.38 MB


http://www.ppmy.cn/news/1341745.html

相关文章

【HarmonyOS应用开发】ArkUI 开发框架-进阶篇-管理组件状态(九)

管理组件状态 一、概述 在应用中&#xff0c;界面通常都是动态的。下图所示&#xff0c;在子目标列表中&#xff0c;当用户点击目标一&#xff0c;目标一会呈现展开状态&#xff0c;再次点击目标一&#xff0c;目标一呈现收起状态。界面会根据不同的状态展示不一样的效果。 Ar…

02-OpenFeign-微服务接入

1、依赖 由于是spring cloud项目&#xff0c;注意spring-boot、cloud、alibaba的版本兼容性 1.1、父级依赖 <properties><java.version>1.8</java.version><spring-boot.version>2.7.18</spring-boot.version><spring.cloud.version>20…

【Simulink系列】——动态系统仿真 之 简单系统

引入 不同的系统具有不同的输入与输出。一般来说&#xff0c;输入输出数目越多&#xff0c;系统越复杂。最简单的系统只要一个输入一个输出&#xff08;SISO&#xff09;&#xff0c;且其任意时刻的输出只与当前时刻的输入有关。 一、简单系统定义 对于满足下列条件的系统&a…

谷粒商城-P19

项目结构创建&提交到码云 数据库初始化 保持docker数据库一直打开 docker update redis --restartalways 连不上了&#xff0c;发现配置文件错了 换了一个配置文件。 快速开发 使用开源的脚手架 人人开源 (gitee.com) 使用renren-fast作为后台开发&#xff0c;使用…

STM32CAN2进入bus off 模式

工作遇到的问题记录 无人机CAN2整个进不了中断&#xff0c;通过查看寄存器判定出CAN节点进入了bus off mode 为何进入bus off &#xff0c;最后通过示波器看到整个CAN2总线波形就不对&#xff0c;总线出现了错误 Busoff的产生是一定是因为节点自身识别到自己发送错误&#xff…

用户体验优化:HubSpot的秘密武器

在当今数字化市场中&#xff0c;提升用户体验已经成为企业成功的关键因素之一。HubSpot&#xff0c;作为一款领先的营销自动化工具&#xff0c;不仅在推动销售业绩上表现出色&#xff0c;同时通过其独特的策略也致力于提升用户体验。运营坛将深入探讨HubSpot是如何通过个性化推…

符号运算 - 华为OD统一考试

OD统一考试&#xff08;C卷&#xff09; 分值&#xff1a; 200分 题解&#xff1a; Java / Python / C 题目描述 给定一个表达式&#xff0c;求其分数计算结果 表达式的限制如下&#xff1a; 所有的输入数字皆为正整数(包括0)仅支持四则运算(*/)和括号结果为整数或分数, 分数…

树莓派zero/zero w的区别

直观区别 1、zero没有WiFi和蓝牙模块&#xff0c;当然也没有网线接口&#xff0c;适合不需要网络的场景需求。 2、zero w带有WiFi和蓝牙模块&#xff0c;没有网线接口。适合需要网络的场景需求。 选购建议 我一般都是看有没有网络接口或者WiFi支持&#xff08;一定要选择焊接…