LeetCode 算法:删除链表的倒数第 N 个结点 c++

原题链接🔗:删除链表的倒数第 N 个结点
难度:中等⭐️⭐️

题目

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

示例 1
在这里插入图片描述

输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
示例 2

输入:head = [1], n = 1
输出:[]

示例 3

输入:head = [1,2], n = 1
输出:[1]

提示

链表中结点的数目为 sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz

进阶:你能尝试使用一趟扫描实现吗?

题解

双指针法

  1. 题解

LeetCode 上的 “删除链表的倒数第 N 个结点” 问题是链表操作中的一个经典问题。这个问题可以通过双指针技术来解决。以下是解题思路:

  • 理解问题:题目要求删除链表中倒数第 N 个节点。例如,如果链表是 1->2->3->4->5,N=2,那么删除后应该是
    1->2->3->5。

  • 使用虚拟头节点:创建一个虚拟头节点,指向原链表的头节点。这样无论原链表的头节点是否被删除,都能保证算法的通用性。

  • 快慢指针:初始化两个指针 fast 和 slow,都指向虚拟头节点。然后移动 fast 指针,使其向前移动 N 步。

  • 同时移动两个指针:接着同时移动 fast 和 slow 指针,直到 fast 指针到达链表的末尾。此时,slow 指针将指向倒数第 N
    个节点的前一个节点。

  • 删除节点:删除 slow 指针的下一个节点,即将 slow->next 指向 slow->next->next。

  • 特殊情况处理:如果 N 大于链表长度,或者链表为空,则无需删除任何节点。

  • 返回结果:返回虚拟头节点的下一个节点,即原链表的新头节点。

  1. 复杂度:时间复杂度O(L),其中L是链表的长度,空间复杂度O(1)。
  2. 代码过程:如demo所示。
  • 首先定义了 ListNode 结构体;
  • 然后实现了 removeNthFromEnd 函数,该函数接收链表的头节点和要删除的节点的索引n。函数内部使用了一个虚拟头节点来简化代码逻辑,并使用双指针技术来找到并删除倒数第 n 个节点。
  • 最后,main 函数中创建了一个示例链表,调用了 removeNthFromEnd函数,并打印了修改后的链表。
  • 最后,不要忘记释放链表占用的内存以避免内存泄漏。
  1. c++ demo
#include <iostream>

// 定义链表节点结构体
struct ListNode {
    int val;
    ListNode* next;
    ListNode(int x) : val(x), next(nullptr) {}
};

// 删除链表的倒数第N个节点
ListNode* removeNthFromEnd(ListNode* head, int n) {
    // 创建虚拟头节点,简化边缘情况处理
    ListNode* dummy = new ListNode(0);
    dummy->next = head;

    // 初始化两个指针,p1 和 p2,都指向虚拟头节点
    ListNode* p1 = dummy, * p2 = dummy;

    // 使 p1 先走 n 步
    for (int i = 0; i < n; ++i) {
        p1 = p1->next;
    }

    // 当 p1 到达第 n 个节点时,p2 开始移动
    // 当 p1 到达链表末尾时,p2 到达倒数第 n 个节点的前一个节点
    while (p1 != nullptr) {
        p1 = p1->next;
        p2 = p2->next;
    }

    // 删除倒数第 n 个节点
    ListNode* toDelete = p2->next;
    p2->next = p2->next->next;

    // 释放被删除节点的内存
    delete toDelete;

    // 返回调整后的链表头节点,注意跳过虚拟头节点
    ListNode* newHead = dummy->next;
    delete dummy; // 释放虚拟头节点
    return newHead;
}

// 打印链表的辅助函数
void printList(ListNode* node) {
    while (node != nullptr) {
        std::cout << node->val << " -> ";
        node = node->next;
    }
    std::cout << "null" << std::endl;
}

// 测试用例
int main() {
    // 创建一个示例链表: 1 -> 2 -> 3 -> 4 -> 5
    ListNode* list = new ListNode(1);
    list->next = new ListNode(2);
    list->next->next = new ListNode(3);
    list->next->next->next = new ListNode(4);
    list->next->next->next->next = new ListNode(5);

    std::cout << "Original List: ";
    printList(list);

    // 删除倒数第 2 个节点
    ListNode* newList = removeNthFromEnd(list, 2);

    std::cout << "Modified List: ";
    printList(newList);

    // 释放链表内存
    while (newList != nullptr) {
        ListNode* temp = newList;
        newList = newList->next;
        delete temp;
    }

    return 0;
}
  • 输出结果:

Original List: 1 -> 2 -> 3 -> 4 -> 5 -> null
Modified List: 1 -> 2 -> 3 -> 4 -> null
在这里插入图片描述

其他方法

  • 计算链表长度法。
  • 栈法。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

opencascade AIS_InteractiveContext源码学习相关枚举 AIS_SelectionScheme AIS_StatusOfPick

AIS_SelectionScheme 枚举 AIS_SelectionScheme 设置交互上下文中的选择方案。 枚举值&#xff1a; AIS_SelectionScheme_UNKNOWN 未定义的方案 AIS_SelectionScheme_Replace 清除当前选择并选择检测到的对象 AIS_SelectionScheme_Add 将检测到的对象添加到当前选择 AIS_…

Artalk-CORS,跨域拦截问题

今天重新部署Artalk之后&#xff0c;遇到了CORS——跨域拦截的问题&#xff0c;卡了好一会记录一下。 起因 重新部署之后&#xff0c;浏览器一直提示CORS&#xff0c;之前在其他项目也遇到过类似的问题&#xff0c;原因就在于跨域问题。

功能测试 之 单模块测试----添加会员

1.需求分析 点击【添加会员】按钮后&#xff0c;页面跳转至添加会员详细页面。 说明&#xff1a; 会员昵称&#xff1a;必填&#xff0c;长度在20个字符&#xff08;除去空格&#xff09;以内&#xff0c;&#xff08;会员昵称&#xff09;可以重复&#xff1b;登录密码&#x…

Java零基础之多线程篇:线程生命周期

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

.net 6 api 修改URL为小写

我们创建的api项目&#xff0c;url是[Route(“[controller]”)]&#xff0c;类似这样子定义的。我们的controller命名是大写字母开头的&#xff0c;显示在url很明显不是很好看&#xff08;url不区分大小写&#xff09;。转换方式&#xff1a; var builder WebApplication.Crea…

【JS重点18】原型链(面试重点)

一&#xff1a;原型链底层原理 以下面一段代码为例&#xff0c;基于原型对象&#xff08;Star构造函数的原型对象&#xff09;的继承使得不同构造函数的原型对象关联在一起&#xff08;此处是最大的构造函数Object原型对象&#xff09;&#xff0c;并且这种关联的关系是一种链…

目标检测——YOLOv10算法解读

论文&#xff1a;YOLOv10: Real-Time End-to-End Object Detection (2024.5.23) 作者&#xff1a;Ao Wang, Hui Chen, Lihao Liu, Kai Chen, Zijia Lin, Jungong Han, Guiguang Ding 链接&#xff1a;https://arxiv.org/abs/2405.14458 代码&#xff1a;https://github.com/THU…

购物网站系统

摘 要 随着互联网的快速发展&#xff0c;不同的平台软件也不断涌出市场&#xff0c;在众多的平台中&#xff0c;购物网站深受人们的欢迎&#xff0c;也成为生活中不可缺少的一部分。经过对国内外购物情况的调查&#xff0c;社区购物在近几年来成为电商发展的新趋势&#xff0c…

Vue - 第3天

文章目录 一、Vue生命周期二、Vue生命周期钩子三、工程化开发和脚手架1. 开发Vue的两种方式2. 脚手架Vue CLI基本介绍&#xff1a;好处&#xff1a;使用步骤&#xff1a; 四、项目目录介绍和运行流程1. 项目目录介绍2. 运行流程 五、组件化开发六、根组件 App.vue1. 根组件介绍…

shell数组

shell数组 文章目录 shell数组数组数组遍历冒泡排序 数组 定义&#xff1a;在集合中指定多个元素&#xff1a;元素的类型&#xff1a;整数。字符串&#xff0c;可以是浮点 作用&#xff1a;一次性的定义多个元素&#xff0c;可以为变量赋值提供便利。 数组的定义方法 数组名…

富唯智能打造的AGV搬运机器人转运机器人

AGV搬运机器人&转运机器人 AGV搬运机器人&#xff0c;内部搭载ICD系列核心控制器&#xff0c;拥有不同的移载平台&#xff0c;负载最高可达 1000kq;重复精度高达5mm;支持 Wi-Fi漫游&#xff0c;实现更稳健的网络数据交互;无轨化激光 SLAM 导航&#xff0c;配合 3D 避障相机…

Flutter-无限循环滚动标签

1. 序章 在现代移动应用开发中&#xff0c;滑动视图是常见的交互模式之一。特别是当你需要展示大量内容时&#xff0c;使用自动滚动的滑动视图可以显著提升用户体验。在这篇文章中&#xff0c;我们将讨论如何使用 Flutter 实现一个自动滚动的列表视图。 2. 效果 3. 实现思路 …

[Linux] 历史根源

UNIX系统&#xff1a; 1969年&#xff0c;由贝尔实验室的K.Thompson和D.M.Ritchie为PDP-7机器编写的一个分时操作系统&#xff0c; 最初使用汇编语言编写&#xff0c; 后来1972年C语言出世以后&#xff0c;二人由使用C写了UNIX3&#xff0c; 此后UNIX大为流行开来 UNIX流派树&a…

凌凯科技冲刺上市:2023年业绩反弹,靠关联交易助推业务发展?

近日&#xff0c;上海凌凯科技股份有限公司&#xff08;下称“凌凯科技”&#xff09;向港交所递交上市申请&#xff0c;华泰国际担任其独家保荐人。 透过招股书不难看出&#xff0c;在化学合成一体化这个虹吸效应显著的细分赛道中&#xff0c;凌凯科技拥有头部玩家的先发优势…

数据分析第十三讲:数据可视化入门(二)

数据可视化入门&#xff08;二&#xff09; 本章我们尝试用 matplotlib 来绘制一些高阶统计图表。正如前面所说的&#xff0c;大家可以通过 matplotlib 官方网站上提供的文档和示例来学习如何使用 matplotlib 并绘制出更加高级的统计图表&#xff1b;尤其是在定制一些比较复杂…

人工智能中的监督学习和无监督学习

欢迎来到 Papicatch的博客 目录 &#x1f349;引言 &#x1f349;监督学习 &#x1f348;基本思想 &#x1f348;具体过程 &#x1f34d;数据收集 &#x1f34d;数据预处理 &#x1f34d;模型选择 &#x1f34d;模型训练 &#x1f34d;模型评估 &#x1f34d;模型部署…

【深度学习基础】详解Pytorch搭建CNN卷积神经网络LeNet-5实现手写数字识别

目录 写在开头 一、CNN的原理 1. 概述 2. 卷积层 内参数&#xff08;卷积核本身&#xff09; 外参数&#xff08;填充和步幅&#xff09; 输入与输出的尺寸关系 3. 多通道问题 多通道输入 多通道输出 4. 池化层 平均汇聚 最大值汇聚 二、手写数字识别 1. 任务…

[C++][数据结构][图][下][最短路径]详细讲解

目录 1.最短路径1.单源最短路径 -- Dijkstra算法2.单源最短路径 -- Bellman-Ford算法3.多源最短路径 -- Floyd-Warshall算法原理 1.最短路径 最短路径问题&#xff1a;从在带权有向图G中的某一顶点出发&#xff0c;找出一条通往另一顶点的最短路径&#xff0c;最短也就是沿路径…

spark学习总结

系列文章目录 第1天总结&#xff1a;spark基础学习 1- Spark基本介绍&#xff08;了解&#xff09;2- Spark入门案例&#xff08;掌握&#xff09;3- 常见面试题&#xff08;掌握&#xff09; 文章目录 系列文章目录前言一、Spark基本介绍1、Spark是什么1.1 定义1.2 Spark与M…

valgrind工具的交叉编译及使用

一 概述 valgrind是一款非常好用的工具&#xff0c;用于检测内存泄漏等&#xff0c;这里讲述如何将其交叉编译到arm开发板及如何使用 【C/C 集成内存调试、内存泄漏检测和性能分析的工具 Valgrind 】Linux 下 Valgrind 工具的全面使用指南 - 知乎 (zhihu.com) valgrind: fai…