力扣题目学习笔记(OC + Swift)19. 删除链表的倒数第 N 个结点

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

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
在这里插入图片描述

此题目为链表题,拿出我们的杀手锏,链表解题经典三把斧:

  • 哑巴节点
  • 快慢指针

关于内存问题:由于Swift及OC均有ARC内存机制,因此删除的节点内容未主动释放,如在手动内存管理的情况下,需要释放被删除节点的内存占用。

方法一、计算链表长度

先求出链表长度L,再将链表从头移动到L-n+1的位置,删除其下一个节点。

时间复杂度:O(n),一次求长度n,极端情况下的一次遍历,2n->O(n)
空间复杂度:O(1)

Swift

//计算链表长度, 删除l-n+1的位置
func removeNthFromEnd(_ head: ListNode?, _ n: Int) -> ListNode? {let dummyNode = ListNode(0, head);let len = getLenOfListNode(head)var current:ListNode? = dummyNodefor _ in 1..<len-n+1 {current = current?.next}current?.next = current?.next?.next//MRC Or ARC?被释放的节点内存需要处理吗?let ans = dummyNode.nextreturn ans}func getLenOfListNode(_ listNode:ListNode?) -> Int {var len = 0var current = listNodewhile let cur = current {current = cur.nextlen += 1}return len}

OC

//计算链表长度, 删除l-n+1的位置
- (ListNodeOC *)removeNthFromEnd:(ListNodeOC *)head atReverseIdx:(NSInteger)n {//构造虚拟头节点ListNodeOC *dummyNode = [[ListNodeOC alloc] initWithVal:0 next:head];NSInteger len = [self lenOfListNode:head];ListNodeOC *cur = dummyNode;for (NSInteger i=1; i<len-n+1; i++) {cur = cur.next;}cur.next = cur.next.next;return dummyNode.next;
}

解法二、栈

先将链表入栈,再出栈n个元素后,栈顶部的元素就是我们需要删除的节点的前一个节点。

时间复杂度:O(n)
空间复杂度:O(n)

Swift

    //入栈后弹栈n次即可func removeNthFromEnd(_ head: ListNode?, _ n: Int) -> ListNode? {//构造影子节点let fickNode = ListNode(0)fickNode.next = headlet stack = Stack<ListNode>()var cur:ListNode? = fickNodewhile let currentNode = cur {stack.push(currentNode)cur = currentNode.next}for _ in 0..<n {let _ = stack.pop()}if let preNode = stack.top() {preNode.next = preNode.next?.next}return fickNode.next}

OC

- (ListNodeOC *)removeNthFromEnd:(ListNodeOC *)head atReverseIdx:(NSInteger)n {ListNodeOC *dummyNode = [[ListNodeOC alloc] initWithVal:0 next:head];StackOC *stack = [[StackOC alloc] init];//先入栈ListNodeOC *cur = dummyNode;while (cur) {[stack push:cur];cur = cur.next;}//出栈n个元素for (NSInteger i=0; i<n; i++) {[stack pop];}//删除最后一个元素cur = [stack top];cur.next = cur.next.next;[stack cleanAll];return dummyNode.next;
}

双指针

创建哑巴节点,有两个指针均指向哑巴节点,首先移动第2个指针n次,此时第1、2个指针相距n个节点;然后同时移动1、2两个节点,直至第2个指针指向最后一个元素,此时的第1个指针指向的节点就是倒数第n个元素的前一个元素。

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

Swift

	func removeNthFromEnd(_ head: ListNode?, _ n: Int) -> ListNode? {//构造影子节点,为指针操作预留空间let dummyNode = ListNode(0, head)var first:ListNode? = dummyNodevar second:ListNode? = dummyNodevar current:ListNode? = dummyNodefor _ in 0..<n {if let cur = current {second = cur.nextcurrent = second}}//同时移动两个指针,直至2到达结尾while let _ = current?.next {first = first?.nextsecond = second?.nextcurrent = second}first?.next = first?.next?.nextreturn dummyNode.next}

OC

- (ListNodeOC *)removeNthFromEnd:(ListNodeOC *)head atReverseIdx:(NSInteger)n {ListNodeOC *dummyNode = [[ListNodeOC alloc] initWithVal:0 next:head];ListNodeOC *firstNode = dummyNode;ListNodeOC *secondNode = dummyNode;//先移动指针,让两个指针差值为nfor (NSInteger i=0; i<n; i++) {secondNode = secondNode.next;}//同时移动两个指针,当第二个指针指向最后一个元素的时候,第一个指针指向的正是倒数第n个元素while (secondNode.next) {firstNode = firstNode.next;secondNode = secondNode.next;}firstNode.next = firstNode.next.next;return dummyNode.next;
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

选择移动订货系统源码的四大原因

移动订货系统需要选择源码支持的厂家&#xff0c;有以下四个原因&#xff0c;其中第四个是比较重要的&#xff0c;大家点个关注点个赞&#xff0c;我们接着往下看。 1.可自行定制&#xff1a;支持源码的移动订货系统可以根据企业的具体需求进行定制开发&#xff0c;满足企业特定…

pyqt5实现wget下载视频文件的进度条显示

简介&#xff1a; 最近在写一个项目&#xff0c;用到了wget下载视频&#xff0c;为了更好的视觉效果&#xff0c;所以使用pyqt5中QProgressBar来实现下载进度条。当视频开始下载就会弹出下载进度条&#xff0c;下载完成后进度条消失。效果如下图; 具体代码实现 &#xff1a; …

FastGPT+ChatGLM3-6b搭建知识库

前言&#xff1a;我用fastgpt直接连接chatglm3&#xff0c;没有使用oneai&#xff0c;不是很复杂&#xff0c;只需要对chatglm3项目代码做少量修改就能支持使用embeddings&#xff0c;向量模型用的m3e&#xff0c;效果还可以 我的配置&#xff1a; 处理器&#xff1a;i5-13500 …

华为云Stack 8.X流量模型分析(三)

三、VPC内部二层流量模型分析 1.不同宿主机下虚拟机互访 VM1发送arp请求&#xff0c;arp报文根据流表到达br-tun&#xff0c;br-tun给予VM1到达VM2的MAC信息。此时arp报文不出宿主机&#xff08;Host1&#xff09;&#xff1b; **注意&#xff1a;**br-tun内的信息是由管理平…

Ignite分布式缓存框架

1.前言 Apache Ignite是一个分布式数据库&#xff0c;支持以内存级的速度进行高性能计算。 2。快速入门 本章节介绍运行Ignite的系统要求&#xff0c;如何安装&#xff0c;启动一个集群&#xff0c;然后运行一个简单的HelloWorld示例。 2.1.环境要求 Apache Ignite官方在如…

110基于matlab的混合方法组合的极限学习机和稀疏表示进行分类

基于matlab的混合方法组合的极限学习机和稀疏表示进行分类。通过将极限学习机&#xff08;ELM&#xff09;和稀疏表示&#xff08;SRC&#xff09;结合到统一框架中&#xff0c;混合分类器具有快速测试&#xff08;ELM的优点&#xff09;的优点&#xff0c;且显示出显着的分类精…

关于频谱仪是如何来实现辐射功率测量

1.1 内部基本原理框架 首先是接收到外部信号输入&#xff0c;然后经过可变衰减器衰减&#xff0c;接着进行变频&#xff0c;接着经过带宽带通滤波器进行滤波&#xff0c;滤波后的信号送入检波器进行信号检测&#xff0c;再经对数放大器放大后&#xff0c;送入低通滤波器进行视频…

java.lang.IllegalStateException: Duplicate key

序言 最近监控扫描出我们项目的某些异常信息&#xff0c;报错java.lang.IllegalStateException: Duplicate key xxx&#xff0c;看到异常来自stream流&#xff0c;然后定位看了一下是某位同事的代码使用stream流把List转Map集合出现重复的key异常信息。List集合A对象来源于某个…

鸿蒙ArkTS语言介绍与TS基础语法

1、ArkTS介绍 ArkTS是HarmonyOS主力应用开发语言&#xff0c;它在TS基础上&#xff0c;匹配ArkUI框架&#xff0c;扩展了声明式UI、状态管理等响应的能力&#xff0c;让开发者以更简洁、更自然的方式开发跨端应用。 JS 是一种属于网络的高级脚本语言&#xff0c;已经被广泛用…

FunBox11靶场 安装下载渗透详细教程

一. 下载靶场 官网下载地址 二. 安装 1.导入FunBox11 三.修改键盘布局和修改IP 参考历史文庄FunBox9安装教程 四. 打靶 1.提供arp-scan工具扫描网络主机IP arp-scan -l -i eh1 2.通过nmap 对目标主机进行扫描 nmap -A -p- -T5 172.30.1.134 -A : 启动Os检测&#xff0c;版…

Qt/QML编程学习之心得:在QML工程中添加库(十四)

实现库并且使用库&#xff0c;类似于vc中的静态库library、动态库dll、COM组件等方法一样&#xff0c;在Qt中也经常会使用库&#xff0c;或者将部分功能打包成库。 右击Qt项目&#xff0c;点击add library... 在linux中将.a文件导入&#xff0c;工程会自动在.pro温江中增加相应…

java定义三套场景接口方案

一、背景 在前后端分离开发的背景下&#xff0c;后端java开发人员现在只需要编写接口接口。特别是使用微服务开发的接口。resful风格接口。那么一般后端接口被调用有下面三种场景。一、不需要用户登录的接口调用&#xff0c;第二、后端管理系统接口调用&#xff08;需要账号密…