力扣题目学习笔记(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.mzph.cn/news/584431.shtml

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

相关文章

算法基础day1

归并排序模版 #include <iostream> using namespace std; int n; const int N 1e610; int q[N],tmp[N]; void merge_sort(int l,int r,int q[]){if(l>r) return;int mid lr>>1;merge_sort(l,mid,q);merge_sort(mid1,r,q);//归并的的过程int k0,il,jmid1;while(…

【Vue2+3入门到实战】(10)Vue基础之一文掌握 组件通信 详细示例(组件通信语法、父传子 、 子传父、非父子通信)

这里写自定义目录标题 一、学习目标1.组件通信2.综合案例&#xff1a;小黑记事本&#xff08;组件版&#xff09; 二、组件通信1.什么是组件通信&#xff1f;2.组件之间如何通信3.组件关系分类4.通信解决方案5.父子通信流程6.父向子通信代码示例7.子向父通信代码示例8.总结 三、…

代码随想录 122. 买卖股票的最佳时机 II

题目 给你一个整数数组 prices &#xff0c;其中 prices[i] 表示某支股票第 i 天的价格。 在每一天&#xff0c;你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买&#xff0c;然后在 同一天 出售。 返回 你能获得的 最大 利润 。 示例 …

FME之读取文件名路径FilenamePartExtractor转换器

在读取文件所在路径及相关信息时&#xff0c;我们除了在读模块时选择Directory and File Pathnames数据类型。还可以选择在某个阶段使用FilenamePartExtractor转换器来读取文件所在路径及相关信息。 在前面转换器只要暴露有fme_dataset&#xff0c;在源文件名选择它即可实现。…

Google Play上架:2023年度总结报告

今天是2023年的最后一个工作日&#xff0c;今天用来总结一下2023年关于谷歌商店上架的相关政策改动和对应的拒审解决方法。 目录 政策更新与改动2023 年 2 月 22 日2023 年 4 月5 日2023 年 7 月 12 日2023 年 10 月 25 日 开发者计划政策拒审邮件内容和解决办法 政策更新与改…

利用Pandas进行高效网络数据获取

利用Pandas进行高效网络数据获取 背景&#xff1a; ​ 最近看到一篇关于使用Pandas模块进行爬虫的文章&#xff0c;觉得很有趣&#xff0c;这里为大家详细说明。 基础铺垫&#xff1a; ​ pd.read_html pandas 库中的一个函数&#xff0c;用于从 HTML 页面中读取表格数据并…

2.如何设置vscode可以搜索node_modules里的内容

在setting.json里添加 {"search.exclude": {"**/node_modules":false},"search.useIgnoreFiles":false }1.将**/node_modules设为false&#xff0c;从而禁用缺省行为&#xff0c;从而支持node_modules目录的检索 对于许多项目而言&#xff0c;将…

数据库 基础面试第一弹

1. SQL语句类型 1. DDL&#xff08;Data Definition Language&#xff0c;数据定义语言&#xff09;&#xff1a; DDL语句用于定义数据库对象&#xff08;如表、索引、视图等&#xff09;。常见的DDL语句包括&#xff1a; CREATE&#xff1a;用于创建数据库对象&#xff0c;如…

【网络安全 | Misc】Training-Stegano-1

该题考察winhex工具使用 打开文件&#xff1a; 使用StegSolve并不能获取有效信息 使用winhex得到flag steganoI

【Linux系统化学习】进程终止的奥秘

个人主页点击直达&#xff1a;小白不是程序媛 Linux专栏&#xff1a;Liunx系统化学习 代码仓库&#xff1a;Gitee 目录 获取函数返回值 退出码 进程退出的场景 错误码 信号终止异常代码 进程的终止 main函数直接return exit函数 _exit函数 获取函数返回值 在C语言学…

玩转区域流量调配,详细解析GLSB是什么?

在互联网早期&#xff0c;由于网络不是很发达&#xff0c;流量也相对比较小&#xff0c;单体架构已经能足够满足需求。但伴随着互联网越来越&#xff0c;网站的流量请求甚至能达到上千亿。为了实现高可用&#xff0c;需要用到多台机器来提升处理流量的能力。在这种环境下&#…

RocketMQ连接报错RemotingConnectException: connect to <192.168.57.129:9876>解决

文章目录 前言一、RocketMQ 连接报错处理1.1 报错信息1.2 修改 broker.conf 文件1.3 Linux 开放端口1.4 项目启动成功 前言 上一篇文章&#xff1a;基于SpringBoot整合RocketMQ异步发送短信功能在项目启动的过程中报了 RocketMQ 连接错误。针对这个问题&#xff0c;本文给予记…

HBase 创建不分裂的表 ( 禁止 Table Split )

注意&#xff1a;由于 HBase 版本众多&#xff0c;配置表的语法在不同版本上会有差异&#xff0c;本文介绍的配置方法是在 1.4.9 版本上测试的&#xff0c;使用 HBase 2.0 的版本需要核实并修改相关配置方法&#xff01; 有时候&#xff0c;出于特殊需要&#xff0c;我们希望对…

Vuex介绍2

续上一个的Vuex今天继续介绍 4 核心概念-getters 除了state之外&#xff0c;优势还需要从state中派生一些状态&#xff0c;这些状态时依赖state的&#xff0c;此时会用到getters 例如&#xff1a;state中定义了list&#xff0c;为1-10的数组&#xff0c;组件中&#xff0c;需…

PIE-Engine简介

PIE-Engine&#xff0c;是航天宏图基于云计算、物联网、大数据和人工智能技术自主研发的一站式地球科学大数据实时计算平台&#xff0c;平台构建了基于云原生的并行高效底层架构&#xff0c;助力地球科学应用的产业化发展。&#xff08;摘自官网&#xff09; 前天&#xff0c;我…

web前端开发网页制作html/css结课作业

效果图展示&#xff1a; 注意事项&#xff1a; 引用JQuery文件地址和图片地址要更换一下。 百度网盘链接&#xff1a; http://链接&#xff1a;https://pan.baidu.com/s/1wYkmLr7csjBwQY6GmlYm4Q?pwd4332 提取码&#xff1a;4332 html界面展示&#xff1a; main.css代码部…

写给工作6年的程序员的一封信

准大牛 &#xff1b;兄&#xff0c; 希望你不会反感我给你的这个特别的称号&#xff0c;我们程序员中的大部分工作到5~6年这个节骨眼上&#xff0c;不出意外的话…准大牛…了&#xff0c;此时的你技术能力正在成熟或者已然成熟&#xff1b;架构设计力初现峥嵘&#xff1b;创新能…

当技术相遇:DevOps之道解析

目录 前言 持续集成/持续交付&#xff08;CI/CD&#xff09; 容器化和编排工具 监控和日志管理 云服务 前言 DevOps是一种软件开发和运维&#xff08;Development Operations&#xff09;的方法论&#xff0c;旨在通过促进开发团队和运维团队之间的合作与沟通&#xff0c…

C++ 结构体(面向对象编程)

面向对象编程的优势 相比于分而治之的结构化程序设计&#xff0c;强调大处着眼的面向对象程序设计的思想&#xff0c;更适合于开发大型软件。得益于数据抽象、代码复用等面象对象的固有特征&#xff0c;软件开发的效率获得极大的提升&#xff0c;成本却大幅降低。 面向对象三…

Linux中磁盘管理与文件系统

目录 一.磁盘基础&#xff1a; 1.磁盘的结构&#xff1a; 2.硬盘的数据结构&#xff1a; 3.硬盘存储容量 &#xff1a; 4.硬盘接口类型&#xff1a; 二.MBR与磁盘分区&#xff1a; 1.MBR的概念&#xff1a; 2.硬盘的分区&#xff1a; 为什么分区&#xff1a; 2.表示&am…