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

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

相关文章

R语言【cli】——通过cli_abort用 cli 格式的内容显示错误、警告或信息,内部调用cli_bullets和inline-makeup

cli_abort(message,...,call .envir,.envir parent.frame(),.frame .envir ) 先从那些不需要下大力气理解的参数入手&#xff1a; 参数【.envir】&#xff1a;进行万能表达式编译的环境。 参数【.frame】&#xff1a;抛出上下文。默认用于参数【.trace_bottom】&#xff…

【华为鸿蒙系统学习】- HarmonyOS4.0之App项目开发|自学篇

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 &#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 目录 创建鸿蒙第一个App项目 项目创建 工程目录区 预览区 运行Hello World 基本工程目录 ws:工…

【Amazon 实验①】Amazon WAF功能增强之实验环境准备

文章目录 1. 实验介绍2. 实验环境准备 1. 实验介绍 在真实的网络空间中&#xff0c;攻击者会使用大量广泛分布的僵尸网络、肉机等发起对目标的攻击。 其来源分布一般比较分散&#xff0c;因此难以简单防范。 本实验联合使用有多种AWS服务&#xff1a;Cloudfront、 Lambdaedge…

『番外篇五』SwiftUI 进阶之如何动态获取任意视图的 tag 和 id 值

概览 在某些场景下,我们需要用代码动态去探查 SwiftUI 视图的信息。比如任意视图的 id 或 tag 值: 如上图所示:我们通过动态探查技术在运行时将 SwiftUI 特定视图的 tag 和 id 值显示在了屏幕上。 这是如何做到的呢? 在本篇博文,您将学到如下内容: 概览1. “如意如意,…

Linux基本内容学习

Linux 命令 文件命令 命令释义语法格式lslist&#xff0c;用于显示目录中文件及其属性信息ls [参数名] [文件名]cdchange directory&#xff0c;用于更改当前所处的工作目录&#xff0c;路径可以是绝对路径&#xff0c;也可以是相对路径&#xff0c;若省略不写则会跳转至当前…

测试工具Jmeter:界面介绍、核心选项说明、核心选项用途

本文章主要介绍Jmeter的界面布局&#xff0c;以及各个选项的功能和它们的用途。 JMeter基本原理是建立一个线程池&#xff0c;多线程运行取样器产生大量负载&#xff0c;在运行过程中通过断言来验证结果的正确性&#xff0c;通过监听器来记录测试结果。 1. Jmeter主界面 当我…

Unresolved plugin: ‘org.apache.maven.plugins‘解决报错

新建springboot项目报Unresolved plugin: ‘org.apache.maven.plugins:maven-surefire-plugin:3.1.2’ 缺什么插件 引入什么插件的依赖就行 <dependency><groupId>org.apache.maven.plugins</groupId><artifactId>maven-install-plugin</artifact…

docker数据卷数据卷容器

前言 今天调休在家&#xff0c;随便玩玩&#xff0c;简单做下学习记录 1. 数据卷特点 数据卷在容器启动时初始化&#xff0c;如果容器使用的镜像在挂载点包含了数据&#xff0c;这些数据会被拷贝到新初始化的数据卷中数据卷可以在容器之间共享和重用可以对数据卷里的内容直接…

重学设计模式-Iterator(迭代器模式)

Iterator迭代器模式 介绍&#xff1a; 迭代器模式是一种行为型设计模式&#xff0c;它允许你在不暴露集合底层表示&#xff08;并不知道集合底层使用何种方式对数据尽心存储&#xff09;的情况下遍历集合中的元素。 这种模式提供了一种方法&#xff0c;可以顺序访问一个聚合…

Tomcat转SpringBoot、tomcat升级到springboot、springmvc改造springboot

Tomcat转SpringBoot、tomcat升级到springboot、springmvc改造springboot 起因&#xff1a;我接手tomcat-springmvc-hibernate项目&#xff0c;使用tomcat时问题不大。自从信创开始&#xff0c;部分市场使用国产中间件&#xff0c;例如第一次听说的宝兰德、东方通&#xff0c;还…

让AIGC成为你的智能外脑,助力你的工作和生活

人工智能成为智能外脑 在当前的科技浪潮中&#xff0c;人工智能技术正在以前所未有的速度改变着我们的生活和工作方式。其中&#xff0c;AIGC技术以其强大的潜力和广泛的应用前景&#xff0c;正在引领着这场革命。 AIGC技术是一种基于人工智能的生成式技术&#xff0c;它可以通…

光模块市场分析与发展趋势预测

光模块是光通信领域的重要组成部分&#xff0c;随着数字经济&#xff0c;大数据&#xff0c;云计算&#xff0c;人工智能等行业的兴起&#xff0c;光模块市场经历了快速发展&#xff0c;逐渐在数据中心、无线回传、电信传输等应用场景中得到广泛应用。本文将基于当前光模块全球…

[JS设计模式]Flyweight Pattern

Flyweight pattern 享元模式是一种结构化的设计模式&#xff0c;主要用于产生大量类似对象而内存又有限的场景。享元模式能节省内存。 假设一个国际化特大城市SZ&#xff1b;它有5个区&#xff0c;分别为nanshan、futian、luohu、baoan、longgang&#xff1b;每个区都有多个图…

STM32F4的DHT11初始化与实例分析

STM32—— DHT11 本文主要涉及STM32F4 的DHT11的使用以及相关时序的介绍&#xff0c;最后有工程下载地址。 文章目录 STM32—— DHT11一、 DHT11的介绍1.1 DHT11的经典电路 二、DHT11的通信2.1 DHT11的传输数据格式2.2 DHT11 通信分步解析 三、 DHT11 代码3.1 引脚图3.2 电路图…

设计师都在用的5个设计灵感网站,赶紧收藏~

设计没灵感&#xff0c;就上这5个网站&#xff0c;绝对能打开新世界大门&#xff0c;全世界设计师的分享、互交站&#xff0c;最优秀的设计作品都在这&#xff0c;赶紧收藏好了~ pinterest​&#xff08;梯子&#xff09; https://www.pinterest.es/ Pinterest是以瀑布流的方式…

基于Java+SpringBoot+Mybaties-plus+Vue+ElementUI+Vant 电影院订票管理系统 的设计与实现

一.项目介绍 基于SpringBootVue 电影院订票管理系统 分为前端和后端。 前端&#xff08;用户&#xff09;&#xff1a; 登录后支持查看首页、电影、影院和我的信息 支持查看正在热映和即将上映的电影信息 支持购票&#xff08;需选择影院座位&#xff09;、看过&#xff08;评论…

千帆 AppBuilder 初体验,不仅解决解决了我筛选简历的痛苦,更是让提效10倍!

文章目录 &#x1f31f; 前言&#x1f31f; 什么是百度智能云千帆 AppBuilder&#x1f31f; 百度智能云千帆 AppBuilder 初体验&#x1f31f; 利用千帆AppBuilder搭建简历小助手&#x1f31f; 让人眼前一亮的神兵利器 - 超级助理 &#x1f31f; 前言 前两天朋友 三掌柜 去北京…

3. BlazorSignalRApp 结合使用 ASP.NET Core SignalR 和 Blazor

参考&#xff1a;https://learn.microsoft.com/zh-cn/aspnet/core/blazor/tutorials/signalr-blazor?viewaspnetcore-8.0&tabsvisual-studio 1.创建新项目 BlazorSignalRApp 2.添加项目依赖项 依赖项&#xff1a;Microsoft.AspNetCore.SignalR.Client 方式1 管理解决方案…

[笔记]ByteBuffer垃圾回收

参考&#xff1a;https://blog.csdn.net/lom9357bye/article/details/133702169 public static void main(String[] args) throws Throwable {List<Object> list new ArrayList<>();Thread thread new Thread(() -> {ByteBuffer byteBuffer ByteBuffer.alloc…

『 C++ 』二叉树进阶OJ题

文章目录 根据二叉树创建字符串 &#x1f996;&#x1f969; 题目描述&#x1f969; 解题思路&#x1f969; 代码 二叉树的层序遍历(分层遍历) &#x1f996;&#x1f969; 题目描述&#x1f969; 解题思路&#x1f969; 代码 二叉树的层序遍历(分层遍历)Ⅱ &#x1f996;&…