当前位置: 首页 > article >正文

可视化图解算法:删除链表中倒数第n个节点

1. 题目

描述

给定一个链表,删除链表的倒数第 n 个节点并返回链表的头指针 例如,

给出的链表为: 1→2→3→4→5, n= 2. 删除了链表的倒数第 n 个节点之后,链表变为1→2→3→5.

数据范围: 链表长度 0≤n≤1000,链表中任意节点的值满足 0≤val≤100

要求:空间复杂度 O(1),时间复杂度 O(n) 备注:

题目保证 n 一定是有效的

示例1

输入:

{1,2},2    

返回值:

{2} 

2. 解题思路

删除链表的倒数第n个节点,需要先找到倒数第n个节点的前一个节点,之后再更改前一个节点的指针域,让它指向下下一个节点,这样就可以将倒数第n个节点删除。快速查找倒数第n个节点可以参考上一篇的内容《可视化图解算法:链表中倒数(最后)k个结点》。

假如要删除的链表结构如下图所示,给定的n=2。即需删除倒数第2个节点,也就是4节点。

我们可以采用以下步骤完成倒数第2个节点的删除:

步骤一:定义快慢指针。

步骤二:移动快指针。

快指针移动n次,每次移动一个节点。

步骤三:快慢指针一起移动。

移动快慢指针(条件是:快指针指向节点的下一个节点为Null)。

步骤四:执行删除节点操作。

slow.next=slow.next.next

步骤五:特殊情况处理。

如果要删除的是头节点,如以下链表,给定的n=2。

特殊情况的判断是:快指针移动n步之后,已经指向了Null。

这时,直接返回头节点的下一个节点即可(原头节点删除,返回新的头节点)。

如果文字描述的不太清楚,你可以参考视频的详细讲解。

  • Python版本:数据结构笔试面试算法-Python语言版_哔哩哔哩_bilibili数据结构笔试面试算法-Python语言版,bilibili课堂,哔哩哔哩课堂,哔哩哔哩,Bilibili,B站,弹幕https://www.bilibili.com/cheese/play/ep1370265

  • Java版本:数据结构笔试面试算法-Java语言版_哔哩哔哩_bilibili数据结构笔试面试算法-Java语言版,bilibili课堂,哔哩哔哩课堂,哔哩哔哩,Bilibili,B站,弹幕https://www.bilibili.com/cheese/play/ep1366721

  • Golang版本:哔哩哔哩_bilibilihttps://www.bilibili.com/cheese/play/ep1364398

3. 编码实现

3.1 Python编码实现

class ListNode:def __init__(self, x):self.val = x  # 链表的数值域self.next = None  # 链表的指针域# 从链表节点尾部添加节点
def insert_node(node, value):if node is None:print("node is None")return# 创建一个新节点new_node = ListNode(value)cur = node# 找到链表的末尾节点while cur.next is not None:cur = cur.next# 末尾节点的next指针域连接新节点cur.next = new_node# 打印链表(从链表头结点开始打印链表的值)
def print_node(node):cur = node# 遍历每一个节点while cur is not None:print(cur.val, end="\t")cur = cur.next  # 更改指针变量的指向print()#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param head ListNode类
# @param n int整型
# @return ListNode类
#
class Solution:def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:# write code hereif head is None:return head# 1. 定义快慢指针fast = headslow = head# 2. 移动快指针for i in range(n):fast = fast.next# 3. 特殊情况判断:是否删除的是头节点if fast is None:return head.next# 4.对于一般情况,移动快慢指针(条件是:快指针指向节点的下一个节点为None)while fast.next is not None:fast = fast.nextslow = slow.next# 5. 执行删除节点操作slow.next = slow.next.nextreturn headif __name__ == '__main__':head = ListNode(1)insert_node(head, 2)insert_node(head, 3)insert_node(head, 4)insert_node(head, 5)print_node(head)s = Solution()node = s.removeNthFromEnd(head, 2)print_node(node)root = ListNode(1)insert_node(root, 2)print_node(root)node1 = s.removeNthFromEnd(root, 2)print_node(node1)

3.2 Java编码实现

package LL09;public class Main {//定义链表节点static class ListNode {private int val;  //链表的数值域private ListNode next; //链表的指针域public ListNode(int data) {this.val = data;this.next = null;}}//添加链表节点private static void insertNode(ListNode node, int data) {if (node == null) {return;}//创建一个新节点ListNode newNode = new ListNode(data);ListNode cur = node;//找到链表的末尾节点while (cur.next != null) {cur = cur.next;}//末尾节点的next指针域连接新节点cur.next = newNode;}//打印链表(从头节点开始打印链表的每一个节点)private static void printNode(ListNode node) {ListNode cur = node;//遍历每一个节点while (cur != null) {System.out.print(cur.val + "\t");cur = cur.next; //更改指针变量的指向}System.out.println();}public static class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** @param head ListNode类* @param n    int整型* @return ListNode类*/public ListNode removeNthFromEnd(ListNode head, int n) {// write code hereif (head == null) {return head;}// 1. 定义快慢指针ListNode fast = head;ListNode slow = head;// 2. 移动快指针for (int i = 0; i < n; i++) {fast = fast.next;}// 3. 特殊情况判断:是否删除的是头节点if (fast == null) {return head.next;}// 4. 对于一般情况,移动快慢指针(条件是:快指针指向节点的下一个节点为null)while (fast.next != null) {fast = fast.next;slow = slow.next;}// 5. 执行删除节点操作slow.next = slow.next.next;return head;}}public static void main(String[] args) {ListNode head = new ListNode(1);insertNode(head, 2);insertNode(head, 3);insertNode(head, 4);insertNode(head, 5);printNode(head);Solution solution = new Solution();ListNode node = solution.removeNthFromEnd(head, 2);printNode(node);ListNode root = new ListNode(1);insertNode(root, 2);printNode(root);ListNode node1 = solution.removeNthFromEnd(root, 2);printNode(node1);}
}

3.3 Golang编码实现

package mainimport "fmt"// ListNode 定义链表节点
type ListNode struct {Val  int       //链表的数值域Next *ListNode //链表的指针域
}/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可*** @param head ListNode类* @param n int整型* @return ListNode类*/
func removeNthFromEnd(head *ListNode, n int) *ListNode {// write code hereif head == nil {return head}// 1. 定义快慢指针fast := headslow := head// 2. 移动快指针for i := 0; i < n; i++ {//不存在:fast==nil。题目要求:n是有效的,即:n<=链表的长度,此种情况不存在fast = fast.Next}// 3. 特殊情况判断:是否删除的是头节点if fast == nil {return head.Next}// 4. 对于一般情况,移动快慢指针(条件是:快指针指向节点的下一个节点为nil)for fast.Next != nil {fast = fast.Nextslow = slow.Next}// 5. 执行删除节点操作slow.Next = slow.Next.Nextreturn head
}
func main() {head := ListNode{Val: 1}head.Insert(2)head.Insert(3)head.Insert(4)head.Insert(5)head.Print()node := removeNthFromEnd(&head, 2)node.Print()root := ListNode{Val: 1}root.Insert(2)root.Print()node1 := removeNthFromEnd(&root, 2)node1.Print()
}// Insert 从链表节点尾部添加节点
func (ln *ListNode) Insert(val int) {if ln == nil {return}//创建一个新节点newNode := &ListNode{Val: val}cur := ln//找到链表的末尾节点for cur.Next != nil {cur = cur.Next}//末尾节点的next指针域连接新节点cur.Next = newNode
}// Print 从链表头结点开始打印链表的值
func (ln *ListNode) Print() {if ln == nil {return}cur := ln//遍历每一个节点for cur != nil {fmt.Print(cur.Val, "\t")cur = cur.Next //更改指针变量的指向}fmt.Println()
}

如果上面的代码理解的不是很清楚,你可以参考视频的详细讲解。

  • Python版本:数据结构笔试面试算法-Python语言版_哔哩哔哩_bilibili数据结构笔试面试算法-Python语言版,bilibili课堂,哔哩哔哩课堂,哔哩哔哩,Bilibili,B站,弹幕https://www.bilibili.com/cheese/play/ep1370265

  • Java版本:数据结构笔试面试算法-Java语言版_哔哩哔哩_bilibili数据结构笔试面试算法-Java语言版,bilibili课堂,哔哩哔哩课堂,哔哩哔哩,Bilibili,B站,弹幕https://www.bilibili.com/cheese/play/ep1366721

  • Golang版本:哔哩哔哩_bilibilihttps://www.bilibili.com/cheese/play/ep1364398

4.小结

删除链表的倒数第n个节点 ,可以通过以下步骤完成:(1)定义快慢指针;(2)移动快指针;(3)快慢指针一起移动;(4)执行删除节点操作;(5)特殊情况处理。难点是很容易忽略特殊情况的处理。

更多算法视频讲解,你可以从以下地址找到:

  • Python编码实现:哔哩哔哩_bilibilihttps://www.bilibili.com/cheese/play/ep1509965

  • Java编码实现:数据结构笔试面试算法-Java语言版_哔哩哔哩_bilibili数据结构笔试面试算法-Java语言版,bilibili课堂,哔哩哔哩课堂,哔哩哔哩,Bilibili,B站,弹幕https://www.bilibili.com/cheese/play/ep1510007

  • Golang编码实现:哔哩哔哩_bilibilihttps://www.bilibili.com/cheese/play/ep1509945

对于链表的相关操作,我们总结了一套【可视化+图解】方法,依据此方法来解决链表相关问题,链表操作变得易于理解,写出来的代码可读性高也不容易出错。具体也可以参考视频详细讲解。

今日佳句:竹外桃花三两枝,春江水暖鸭先知。

相关文章:

可视化图解算法:删除链表中倒数第n个节点

1. 题目 描述 给定一个链表&#xff0c;删除链表的倒数第 n 个节点并返回链表的头指针 例如&#xff0c; 给出的链表为: 1→2→3→4→5, n 2. 删除了链表的倒数第 n 个节点之后,链表变为1→2→3→5. 数据范围&#xff1a; 链表长度 0≤n≤1000&#xff0c;链表中任意节点的…...

智能汽车图像及视频处理方案,支持视频智能拍摄能力

美摄科技&#xff0c;作为智能汽车图像及视频处理领域的先行者&#xff0c;凭借其卓越的技术实力和前瞻性的设计理念&#xff0c;为全球智能汽车制造商带来了一场视觉盛宴的革新。我们自豪地推出——美摄科技智能汽车图像及视频处理方案&#xff0c;一个集高效性、智能化、画质…...

如何根据 CUDA 配置安装 PyTorch 和 torchvision(大模型 环境经验)

目录 前言1. CUDA2. 环境配置前言 🤟 找工作,来万码优才:👉 #小程序://万码优才/r6rqmzDaXpYkJZF 写过ubuntu的配置安装:Ubuntu安装配置Cuda和Pytorch gpu 以下针对Window,如何通过Cuda配置对应版本,安装大模型环境! 代码有配置包,直接执行:pip install -r requi…...

微信小程序的业务域名配置(通过ingress网关的注解)

一、背景 微信小程序的业务域名配置&#xff08;通过kong网关的pre-function配置&#xff09;是依靠kong实现&#xff0c;本文将通过ingress网关实现。 而我们的服务是部署于阿里云K8S容器&#xff0c;当然内核与ingress无异。 找到k8s–>网络–>路由 二、ingress注解 …...

自学Python创建强大AI:从入门到实现DeepSeek级别的AI

人工智能&#xff08;AI&#xff09;是当今科技领域最热门的方向之一&#xff0c;而Python是AI开发的首选语言。无论是机器学习、深度学习还是自然语言处理&#xff0c;Python都提供了丰富的库和工具。如果你梦想创建一个像DeepSeek这样强大的AI系统&#xff0c;本文将为你提供…...

Matlab 舰载机自动着舰控制系统研究

1、内容简介 Matlab 188-舰载机自动着舰控制系统研究 可以交流、咨询、答疑 2、内容说明 略 3、仿真分析 略 4、参考论文 略...

【华为OD-E卷 -123 判断一组不等式是否满足约束并输出最大差 100分(python、java、c++、js、c)】

【华为OD-E卷 - 判断一组不等式是否满足约束并输出最大差 100分(python、java、c++、js、c)】 题目 给定一组不等式,判断是否成立并输出不等式的最大差(输出浮点数的整数部分) 要求: 不等式系数为 double类型,是一个二维数组 不等式的变量为 int类型,是一维数组; 不等式…...

剑指 Offer II 113. 课程顺序

comments: true edit_url: https://github.com/doocs/leetcode/edit/main/lcof2/%E5%89%91%E6%8C%87%20Offer%20II%20113.%20%E8%AF%BE%E7%A8%8B%E9%A1%BA%E5%BA%8F/README.md 剑指 Offer II 113. 课程顺序 题目描述 现在总共有 numCourses 门课需要选&#xff0c;记为 0 到 n…...

小科普《DNS服务器》

DNS服务器详解 1. 定义与核心作用 DNS&#xff08;域名系统&#xff09;服务器是互联网的核心基础设施&#xff0c;负责将人类可读的域名&#xff08;如www.example.com&#xff09;转换为机器可识别的IP地址&#xff08;如192.0.2.1&#xff09;&#xff0c;从而实现设备间的…...

嵌入式硬件篇---WIFI模块

文章目录 前言一、核心工作原理1. 物理层&#xff08;PHY&#xff09;工作频段2.4GHz5GHz 调制技术直接序列扩频正交频分复用高效数据编码 2. 协议栈架构MAC层Beacon帧4次握手 3. 核心工作模式 二、典型应用场景1. 智能家居系统远程控制环境监测视频监测 2. 工业物联网设备远程…...

WindowsAD域服务权限提升漏洞

WindowsAD 域服务权限提升漏洞&#xff08;CVE-2021-42287, CVE-2021-42278&#xff09; 1.漏洞描述 Windows域服务权限提升漏洞&#xff08;CVE-2021-42287, CVE-2021-42278&#xff09;是由于Active Directory 域服务没有进行适当的安全限制&#xff0c;导致可绕过安…...

Oracle常见系统函数

一、字符类函数 1&#xff0c;ASCII(c)和CHR(i)字符串和ascii码互转换 SQL> select ascii(Z) ,ascii(H),ascii( A) from dual;ASCII(Z) ASCII(H) ASCII(A) ---------- ---------- ----------90 72 32SQL> select chr(90),chr(72),chr(65) from dual;C…...

甘特图dhtmlx-gantt 一行多任务

继上篇进行修改 dhtmlxGantt 甘特图 一行展示多条任务类型_dhtmlxgantt多个任务显示在一行-CSDN博客 主要修改 getProductData 数据部分&#xff1a; 数据中添加&#xff1a; render: "split", //允许任务在同一行中拆分显示&#xff0c; parent: "1",…...

docker配置国内镜像站链接

修改这个文件 sudo vi /etc/docker/daemon.json将镜像站的链接放在里面&#xff0c;如果大于等于两个用逗号分隔 { "registry-mirrors": ["https://docker.1panel.live"] }使配置生效 sudo systemctl daemon-reload sudo systemctl restart docker条件允…...

Flutter 学习之旅 之 flutter 使用 SQLite(sqflite) 实现简单的数据本地化 保存/获取/移除/判断是否存在 的简单封装

Flutter 学习之旅 之 flutter 使用 SQLite&#xff08;sqflite&#xff09; 实现简单的数据本地化 保存/获取/移除/判断是否存在 的简单封装 目录 Flutter 学习之旅 之 flutter 使用 SQLite&#xff08;sqflite&#xff09; 实现简单的数据本地化 保存/获取/移除/判断是否存在…...

【leetcode hot 100 208】实现Trie(前缀树)

解法一&#xff1a;字典树 Trie&#xff0c;又称前缀树或字典树&#xff0c;是一棵有根树&#xff0c;其每个节点包含以下字段&#xff1a; 指向子节点的指针数组 children。对于本题而言&#xff0c;数组长度为 26&#xff0c;即小写英文字母的数量。此时 children[0] 对应小…...

Pytest的夹具共享(2)

1、问题&#xff1a;夹具跟用例都是写在一个py文件中&#xff0c;在自动化框架中&#xff0c;测试用例、夹具在不同的文件中&#xff0c;跨文件夹具使用呢&#xff1f; “”" 在XXX测试用例模块中&#xff0c;使用夹具&#xff1f; 如何跨文件调用&#xff1f; -1&#x…...

前端安全之DOMPurify基础使用

DOMPurify时一款专门用于防御XSS攻击的库&#xff0c;通过净化HTML的内容&#xff0c;移除恶意脚本&#xff0c;同时保留安全的HTML标签和数学。以下是基础使用指南&#xff0c;涵盖基础的安装与用法。 1&#xff0c;安装DOMPurify 通过npm或yarn安装 npm install dompurify …...

鸿蒙 元服务摘要

元服务&#xff08;原名原子化服务&#xff09;&#xff0c;是HarmonyOS提供的一种面向未来的服务提供方式&#xff0c;是有独立入口的&#xff08;用户可通过点击方式直接触发&#xff09;、免安装的&#xff08;无需显式安装&#xff0c;由系统程序框架后台安装后即可使用&am…...

【css酷炫效果】纯CSS实现粒子旋转动画

【css酷炫效果】纯CSS实现粒子旋转动画 缘创作背景html结构css样式完整代码效果图 想直接拿走的老板&#xff0c;链接放在这里&#xff1a;https://download.csdn.net/download/u011561335/90492008 缘 创作随缘&#xff0c;不定时更新。 创作背景 刚看到csdn出活动了&…...

k8s中的service解析

k8s中的service解析 在k8s中&#xff0c;我们可以通过pod来创建服务。 然而&#xff0c;当我们创建多个 Pod 来提供同一项服务时&#xff0c;直接通过 Pod IP 进行访问会变得复杂且不可维护。因此&#xff0c;Kubernetes 提供了 Service 这一抽象概念&#xff0c;用于对外暴露…...

案例:图书管理

掌握图书管理案例的实现&#xff0c;能够使用Spring Boot整合Thymeleaf完成图书管理案例。 1.任务需求 &#xff08;1&#xff09;项目使用Spring Boot整合Thymeleaf&#xff0c;项目展示的页面效果全部通过Thymeleaf的模板文件实现。 &#xff08;2&#xff09;查询所有图书。…...

Docker和Dify学习笔记

文章目录 1 docker学习1.1 基本命令使用1.1.1 docker ps查看当前正在运行的镜像1.1.2 docker stop停止容器1.1.3 docker compose容器编排1.1.4 docker网络[1] 进入到容器里面敲命令[2] docker network ls[3] brige网络模式下容器访问宿主机的方式 2 Dify的安装和基础使用2.1 下…...

【Java集合夜话】第1篇:拨开迷雾,探寻集合框架的精妙设计

欢迎来到Java集合框架系列的第一篇文章&#xff01;&#x1f339; 本系列文章将以通俗易懂的语言&#xff0c;结合实际开发经验&#xff0c;带您深入理解Java集合框架的设计智慧。&#x1f339; 若文章中有任何不准确或需要改进的地方&#xff0c;欢迎大家指出&#xff0c;让我…...

VSCode创建VUE项目(四)增加用户Session管理

将用户信息存储或者更新到Session sessionStorage.setItem("userID",loginform.value.username); sessionStorage.setItem(loginTime, Date.now()); 获取Session信息 const storedUserInfo sessionStorage.getItem(userID); const loginTime sessionStorage.get…...

线性代数(1)用 excel 计算鸡兔同笼

线性代数excel计算鸡兔同笼 案例&#xff1a;鸡兔同笼问题的三种解法&#xff08;递进式教学&#xff09;一、问题描述二、方程式解法&#xff08;基础版&#xff09;步骤解析 三、线性代数解法&#xff08;进阶版&#xff09;1. 方程组转化为矩阵形式2. 矩阵求解&#xff08;逆…...

Qt中多线程

在Qt中实现多线程主要有两种常用方式&#xff1a;基于QThread的子类化和QObjectmoveToThread的Worker模式。以下是详细说明和示例代码&#xff1a; 1. 传统方法&#xff1a;继承 QThread&#xff08;适用于简单任务&#xff09; #include <QThread> #include <QDebug…...

Grokking System Design 系统设计面试问题

《Grokking the System Design Interview》列举了多个经典的系统设计题目,通常按照 不同的业务场景和技术难点 进行分类。以下是一些常见的分类和题目示例: 1. 社交网络类 设计 Twitter(支持关注/取关、推文、Feed 流) 设计 Facebook Messenger(即时聊天,支持在线/离线状…...

Android Launcher3 首屏图标锁定技术方案解析

一、需求背景与技术挑战 在Android 13系统定制开发中&#xff0c;需实现Launcher首屏图标固定功能。该需求需在以下技术维度进行突破&#xff1a; 拖拽事件拦截机制&#xff1a;需精准识别拖拽目标区域 布局层级判定&#xff1a;准确识别第一屏的布局标识 跨屏操作限制&…...

hubilder打包ios app, 并上传TestFlight

目录 一 前提条件 不是该项目成员解决 1. 直接找到该项目的管理人员去设置你的账号 2. 直接重新生成APPID(一般不建议的&#xff0c;可以查看) 3. 如果是离职人员&#xff0c;可以让他将项目权限转让出来 - 如何转让应用 - DCloud问答 未申请ios证书和描述文件 APP ID 的…...