【leetcode】链表总结

news2024/9/24 9:19:28

说明:本文内容来自于代码随想录

image.png

链表基本操作

https://leetcode.cn/problems/design-linked-list/

删除节点

https://leetcode.cn/problems/remove-linked-list-elements/description/,删除节点,虚拟头节点。定义两个节点,分别为前继节点 pre 和当前节点 cur。当前节点初始化为头节点。每次判断当前节点是否需要删除。若要删除,则将前继节点的下一个指向当前节点的下一个;否则,更新前继节点为当前节点。最后当前节点移动到下一个节点。
要点:

  1. 头节点的删除和其他节点的删除是不一样的。因为删除是将被删除节点的前继节点指向被删除节点的后继,但是头节点没有前继。所以需要定义一个虚拟头节点,其后继指向 head
  2. 删除后,新的头节点为虚拟头节点的后继

代码如下:

public ListNode removeElements(ListNode head, int val) {
    // 前继节点的下一个指向当前节点
    // 若当前节点需要删除,则将前继节点的下一个指向当前节点的下一个

    ListNode dummy = new ListNode(-1, head); // 虚拟节点,指向头节点
    ListNode pre = dummy;
    ListNode cur = head;
    while (cur != null) {
        if (cur.val == val) { // 当前节点需要删除
            pre.next = cur.next;
        } else { // 当前节点不需要删除,则更新前继节点为当前节点
            pre = cur; 
        }
        cur = cur.next; // 当前节点往前移动一位
    }

    // 最开始,pre.next和dummy指向的实际上是同一个地址。当pre.next发生变化时,dummy.next也发生变化
    // 但是pre和dummy不是同一个地址。所以当修改pre = cur时,dummy是不变的。

    // 所以最开始如果pre.next发生了更新的话,那么dummy.next也会同步更新,即更新的是头节点。
    // 一旦pre发生了更新,则下一次的pre.next更新就不会影响头节点了,影响的是头节点后面的节点。
    return dummy.next;
}

在头部插入节点

public ListNode insertHead(ListNode head, int val) {
    ListNode newNode = new ListNode(val);
    newNode.next = head; // 新节点的后继指向旧头节点
    head = newNode; // 更新头节点为新节点
    return head;
}

反转链表

思路:

  1. 用两个指针分别指向前一个 pre 和当前节点 cur,当前节点初始化为头节点 pre=head
  2. 每次操作,头节点指向前一个,cur.next = pre,然后 pre 和 cur 分别前进一个单位
  3. 由于改变了 cur 的下一个之后,前进的时候就无法找到原来的下一个了,所以需要在操作之前暂存下一个 next = cur.next

动画:
https://code-thinking.cdn.bcebos.com/gifs/206.%E7%BF%BB%E8%BD%AC%E9%93%BE%E8%A1%A8.gif
迭代版

public ListNode reverseList(ListNode head) {
    ListNode pre = null;
    ListNode cur = head;
    while (cur != null) {
        // 保存cur的下一个节点
        ListNode next = cur.next;
        cur.next = pre;

        pre = cur;
        cur = next;
    }

    return pre;
}

递归版

public ListNode reverse(ListNode pre, ListNode cur) {
    if (cur == null) return pre;

    // 反转
    ListNode next = cur.next;
    cur.next = pre;
    
    return reverse(cur, next);
}

public ListNode reverseList(ListNode head) {
    ListNode pre = null;
    ListNode cur = head;
    return reverse(pre, cur);
}

交换成对节点

https://leetcode.cn/problems/swap-nodes-in-pairs/description/
image.png
交换涉及到 3 步,所以需要 3 个指针 pre, cur, next,分别表示上一个的前继、上一个、下一个(注意图中的 cur 指的是这里的 pre,图里的 1 是这里的 cur,图里的 2 是这里的 next):

  1. 上一个的后继指向下一个的后继,cur.next = next.next
  2. 下一个的后继指向上一个,next.next = cur
  3. 上一个的前继的后继指向下一个,pre.next = next
// 交换
cur.next = next.next;
next.next = cur;
pre.next = next;

注意需要更新头节点,即:当第一次交换完之后,更新头节点为 next

删除链表倒数第 n 个节点

链表相交

环形链表

总结

image.png
哑节点(dummy node)在链表中很常用,比如:

  • 删除节点,涉及到 2 个节点,当前节点 cur 和当前节点的前继 pre。如果删除的是头节点,就没有前继,所以需要哑节点
  • 交换节点,涉及到 3 个节点,当前节点 cur、当前节点的前继 pre、当前节点的后继 next。类似的,头节点没有前继,所以需要哑节点

说明:由于这些操作有可能会修改头节点,所以在操作的时候,除了哑节点 dummy,还要定义 pre 节点:

  1. 初始化,pre = dummy
  2. 后续的操作中,只移动 pre,dummy 保持不变
  3. 由于第一次 pre 和 dummy 的后继指向的是同一个,所以 pre 的后继更新了,dummy 的后继也会更新,即达到了更新头节点的目的。后续移动 pre 之后,pre 的后继和 dummy 的后继就不是同一个了, dummy 的后继就不会在更新了

在这里插入图片描述

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

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

相关文章

服务器数据恢复—raid5热备盘未激活崩溃导致上层oracle数据丢失的数据恢复案例

服务器数据恢复环境: 某品牌X系列服务器,4块SAS硬盘组建了一组RAID5阵列,还有1块磁盘作为热备盘使用。服务器上层安装的linux操作系统,操作系统上部署了一个基于oracle数据库的OA(oracle已经不再为该OA系统提供后续服务…

域名、DNS 和 IP是什么?网站搭建的必备知识,一文搞定

在正式进行WordPress站点搭建前,有一些最基础的知识是必备的,这篇文章会详细介绍给大家。 一、域名、DNS和IP的关系 域名、DNS和IP是互联网上的三个重要的概念,它们之间有着密切的联系,也影响着我们访问网站的方式和效果。接下来…

GPM降水数据下载-Linux系统上使用wget

Linux 上如何下载GPM降水数据 图片来自:https://disc.gsfc.nasa.gov/datasets/GPM_3IMERGHHL_06/summary?keywordsGPM 这里以GPM30min降水数据为例, GPM下载链接 如果进不去,可能需要在这个网址上先注册个账户,这里不做介绍。 …

【C语言】printf()函数详解,手把手教你,保姆级!!!

目录 基本用法 printf()函数--占位符 占位符大全 printf()函数--限定宽度 printf()函数--正负--限定小数 printf()函数--输出部分字符串 总结 【C语言】printf()函数详解,手把手教你,保姆级!!! 基本用法 printf()…

物联网终端设备众多,为何遥测终端机备受瞩目?

遥测终端机是一种用于数据采集、远程传输、数据存储与处理的综合体设备,已逐渐成为现代智能物联领域的焦点。遥测终端机集成了多种传感器与通信模块,能够实时采集各种环境参数,如温度、湿度、压力、流量等,同时支持无线通信&#…

c语言->浅学结构体

系列文章目录 文章目录 前言 ✅作者简介:大家好,我是橘橙黄又青,一个想要与大家共同进步的男人😉😉 🍎个人主页:橘橙黄又青_C语言,函数,指针-CSDN博客 目的:学习结构体基础内容&am…

在qemu平台使用gdb调试程序

1、使用gdb在qemu上调试程序 1.1、第一步:在qemu上运行程序并开启gdb server qemu-system-riscv64 -nographic -machine virt -m 128M -smp 1 -kernel …/bin/test.elf -s -S 1.2、第二步:使用gdb客户端连接gdb server -x:指定gdb的配置文件…

QEMU源码全解析 —— virtio(2)

接前一篇文章: 本文内容参考: 《趣谈Linux操作系统》 —— 刘超,极客时间 《QEMU/KVM》源码解析与应用 —— 李强,机械工业出版社 特此致谢! 上一回对于virtio进行了简介,并说明了其基本原理以及框架。对…

大创项目推荐 深度学习 python opencv 实现人脸年龄性别识别

文章目录 0 前言1 项目课题介绍2 关键技术2.1 卷积神经网络2.2 卷积层2.3 池化层2.4 激活函数:2.5 全连接层 3 使用tensorflow中keras模块实现卷积神经网络4 Keras介绍4.1 Keras深度学习模型4.2 Keras中重要的预定义对象4.3 Keras的网络层构造 5 数据集处理训练5.1 …

玩转树莓派之系统安装篇

介绍 树莓派是树莓派基金会下的一个明星产品(单板计算机),已经迭代到第五代了;它性能强大、开源、拓展性强、体积小,搞物联网开发的人基本都听说过这个玩意!笔者手上刚好有一块4B的板子,让我们…

动态通讯录(并不难都能拿下)

文章目录 🚀前言🚀通讯录实现动态通讯录的初期准备模块化框架搭建 🚀实现接口函数 🚀前言 铁子们好啊!今天咱们来整一个有意思的玩意——通讯录,相信大家对通讯录并不陌生,那接下来就跟着阿辉把…

Linux--LAMP 平台部署及应用

5.1 LAMP平台概述 LAMP架构是目前成熟的企业网站应用模式之一,指的是协同工作的一整套系统和相关软件,能够提供动态Web站点服务及其应用开发环境。LAMP是一个缩写词,具体包括Linux操作系统,Apache 网站服务器、MySQL数据库服务器&…

互联网加竞赛 python+opencv+机器学习车牌识别

0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 基于机器学习的车牌识别系统 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:4分工作量:4分创新点:3分 该项目较为新颖,适…

EnlightenGAN论文阅读笔记

EnlightenGAN论文阅读笔记 论文是2019年IEEE的EnlightenGAN: Deep Light Enhancement without Paired Supervision.这篇论文是低光增强领域无监督学习的开山之作。 论文链接如下:arxiv.org/pdf/1906.06972.pdf 文章目录 EnlightenGAN论文阅读笔记出发点**出发点1**&…

linux应用程序直接return与exit的区别

在Linux应用程序中,可以使用return语句直接从main函数返回。这将导致程序终止并返回给操作系统。然而,有时候使用exit函数比直接使用return语句更有优势,以下是一些原因: 清理资源:exit函数可以确保在程序终止之前执行…

Aurora8B10B(二) 从手册和仿真学习Aurora8B10B

一. 简介 在上篇文章中,主要结合IP配置界面介绍了一下Aurora8B10B,这篇文章将结合文档来学习一下Aurora8B10B内部的一些细节 和 相关的时序吧。文档主要是参考的是这个 pg046-aurora-8b10b-en-us-11.1 二. Aurora8B10B内部细节 在手册上,对…

pytorch中数据预处理模块:transforms详解

1 tranforms概述 1.1 torchvision介绍 torchvision是pytorch的计算机视觉工具包,主要有以下三个模块: torchvision.transforms:提供了常用的一系列图像预处理方法,例如数据的标准化,中心化,旋转&#xff…

设计模式——外观模式(结构型)

引言 外观模式是一种结构型设计模式, 能为程序库、 框架或其他复杂类提供一个简单的接口。 ​ 问题 假设你必须在代码中使用某个复杂的库或框架中的众多对象。 正常情况下, 你需要负责所有对象的初始化工作、 管理其依赖关系并按正确的顺序执行方法等。…

记录 | 不限速下载vscode

在下载 vscode 的时候往往会遇到一个问题就是下载的贼慢 下面教不限速下载的方式 将下面红框内的内容进行替换 替换为: vscode.cdn.azure.cn然后你会发现下载速度就起飞了