力扣题目学习笔记(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://xiahunao.cn/news/2661974.html

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

相关文章

无论男孩女孩都要尽情打扮

这款柔软又细腻的开衫外套 上身体验感很不错的哈 舒适软糯百搭还透气&#xff0c;抗起球的面料 黑灰两色简单大方 胸前加上了流行的刺绣设计&#xff0c;可爱又精致 单穿内搭都可&#xff0c;现在天气还比较冷 外面可以套个羽绒服之类的 时尚叠穿风&#xff0c;韩系范儿…

Web自动化测试:Selenium入门到精通

前言 说到自动化测试&#xff0c;就不得不提大名鼎鼎的Selenium。Selenium 是如今最常用的自动化测试工具之一&#xff0c;支持快速开发自动化测试框架&#xff0c;且支持在多种浏览器上执行测试。 Selenium学习难度小&#xff0c;开发周期短。对测试人员来说&#xff0c;如果…

模版匹配历劫之路1-匹配点太多如何解决

1测试图片 2初步推测是否是提取的点太多而导致匹配时间很长 2.1通过canny的算法来提取检测点 import numpy as np import cv2 import time import matplotlib.pyplot as pltclass GeoMatch:def __init__(self):self.noOfCordinates0 # 坐标数组中元素的个数self.cordinates…

ArcGIS批量计算shp面积并导出shp数据总面积(建模法)

在处理shp数据时&#xff0c; 又是我们需要知道许多个shp字段的批量计算&#xff0c;例如计算shp的总面积、面积平均值等&#xff0c;但是单个查看shp文件的属性进行汇总过于繁琐&#xff0c;因此可以借助建模批处理来计算。 首先准备数据&#xff1a;一个含有多个shp的文件夹。…

C++ Qt开发:SqlRelationalTable关联表组件

Qt 是一个跨平台C图形界面开发库&#xff0c;利用Qt可以快速开发跨平台窗体应用程序&#xff0c;在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置&#xff0c;实现图形化开发极大的方便了开发效率&#xff0c;本章将重点介绍SqlRelationalTable关联表组件的常用方法及灵…

想畅游在全球顶级金融学识的海洋——人民大学与加拿大女王大学金融硕士

金融职场的你是否想象过有朝一日能够畅游在全球顶级金融学识的海洋中呢&#xff1f;在那里&#xff0c;你可以尽情探索和领略全球顶尖的金融学识的魅力与深度&#xff0c;与来自世界各地的专业人士共同交流和分享经验。这样的场景让人感到兴奋和向往&#xff0c;准备好了吗&…

Goal-Auxiliary Actor-Critic for 6D Robotic Grasping with Point Clouds

题目&#xff1a;基于点云的 6D 机器人抓取目标-辅助行为-评价 摘要&#xff1a;6D 机 器 人 抓 取超 越 自上 而 下捡 垃 圾桶 场 景是 一 项具 有 挑战 性 的任 务 。 以往基于 6 D 抓 取综 合和 机器 人运 动 规划 的解 决方 案 通常 在开 环设 置下 运 行&#xff0c; 对抓…

轻松实现电脑对iPhone应用管理

目录 摘要 引言 用户登录工具和连接设备 电脑可对手机应用程序批量操作 运行APP和查看APP日志 IPA包安装测试 摘要 本文介绍了如何使用克魔助手工具实现电脑对手机应用的管理操作。通过简单的步骤&#xff0c;用户可以批量操作手机应用、运行应用、查看应用日志以及安装测…

企业如何做好内容?媒介盒子分享

在个性化算法的支持下&#xff0c;企业通过创作优质内容使消费者主动选择企业的时代已经来临&#xff0c;对于中小企业来说&#xff0c;这是能够低成本进行营销的好机会。但是有许多企业对内容的理解依旧是片面的&#xff0c;今天媒介盒子就来和大家聊聊&#xff1a;企业如何做…

autosar SJBWY 开发

第一天&#xff1a; 解决tasking 增加任意目录源文件的问题&#xff1b; 展开 Advanced 下面 Browse...选你的源文件目录就好了&#xff1b;

彭涛:2023年终复盘,工作,团队,个人!

眨眼2023即将结束&#xff0c;2024即将开启&#xff0c;每年这个时候&#xff0c;都会简单总结下自己这一年&#xff0c;既是对今年的一个复盘和回顾&#xff0c;也是对新一年的向往和期待。 我的2023年&#xff0c;大概分为 「个人」&#xff0c;「家庭」&#xff0c;「团队」…

第二证券:道指再创历史新高,国际油价大跌超2.5%

当地时间周四&#xff0c;美股收盘涨跌不一&#xff0c;道指再创前史新高&#xff0c;标普500指数进一步迫临前史纪录。到收盘&#xff0c;道指涨53.58点&#xff0c;涨幅为0.14%&#xff0c;报37710.10点&#xff1b;标普500指数涨1.77点&#xff0c;涨幅为0.04%&#xff0c;报…

99. 恢复二叉搜索树

#中序遍历&#xff0c;寻找插值位置并交换 # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # self.val val # self.left left # self.right right class Solution:def recoverTree…

啥是构造器?

当我们new一个对象时就是在引用构造器 构造器又叫做构造函数 构造函数一般分为无参构造函数与有参构造函数 假设我们创建一个pet类&#xff0c;这个类里面就会有一个看不见的自动生成的无参构造函数 如果pet类里没有这个隐形的无参构造&#xff0c;我们new一个对象时就会报错…

ArcGIS高程点生成等高线

基本步骤&#xff1a;数据清洗→创建TIN→TIN转栅格→等值线→平滑线。 1.&#xff08;重要&#xff09;数据清理&#xff1a;删除高程点中的高程异常值数据。 2.创建TIN:系统工具→3D Analyst Tools→数据管理→TIN→创建TIN&#xff08;可直接搜索工具TIN&#xff09;。 单击…

铂炭催化剂,2026年市场预计将以6.5%左右的复合年增长率增长

铂碳催化剂广泛用于各种工业应用&#xff0c;包括化学、制药和汽车领域。在对清洁能源的需求不断增加和环境问题意识不断提高的推动下&#xff0c;铂碳催化剂市场正在稳步增长。本次分析&#xff0c;我们将从全球市场和中国市场分别考察铂碳催化剂市场的发展趋势。 全球市场分析…

OSPF ROUTER-ID-新版(15)

目录 整体拓扑 操作步骤 1.INT 验证Router-ID选举规则 1.1 查看路由器Router-ID 1.2 配置R1地址 1.3 查看R1接口信息 1.4 查看R1Router-ID 1.5 删除接口IP并查看Router-ID 1.6 手工配置Router-ID 2.基本配置 2.1 配置R1的IP 2.2 配置R2的IP 2.3 配置R3的IP 2.4 配…

winserver2008 r2服务器iis配置支持flv,f4v,mp4格式视频

很多政府单位网站一直在使用WIN服务器&#xff0c;大部分网站都使用多年基本使用.NET或者CMS系统建站&#xff0c;系统环境也一直是老版本&#xff0c;今天在维护过程中又出现了新问题&#xff0c;上传的MP4文件不支持网站上播放&#xff0c;顺便也分享下解决过程。当我们架设的…

在VMware安装CentOS 7:详细教程

安装准备工作 本地虚拟机&#xff1a;我这里使用的是VMware Workstation 17 Pro centos7系统ISO镜像&#xff1a;我这里使用的是CentOS-7-x86_64-DVD-2009.iso&#xff0c;具体的下载地址是在阿里云官方镜像站&#xff1a;centos-7.9.2009-isos-x86_64安装包下载_开源镜像站-阿…

Springboot启动流程-持续记录中

注:转载请携带本文链接及公众号信息 公众号&#xff1a;codelike 基于springboot2.6.x 源码 Springboot启动之第一篇 SpringApplication构造器 启动入口方法是new SpringApplication.run(),一切的开始都从这里 这里做了什么呢 分为初始化SpringApplication实体、执行run()…