LeetCode-链表操作题目

news2025/7/26 19:34:18

虚拟头指针,在当前head的前面建立一个虚拟头指针,然后哪怕当前的head的val等于提供的val也能进行统一操作


203移除链表元素简单题

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode removeElements(ListNode head, int val) {
        //为了统一操作,创建虚拟头指针
        ListNode fakehead=new ListNode();
        //虚拟头指针指向head,然后做判断
        fakehead.next=head;

        ListNode current=fakehead;
        while(current.next!=null)
        {
            //只要头指针的next不是空指针,等于val就删除,不等于就指向下一个指针
            if(current.next.val==val)
            {
                current.next=current.next.next;
            }
            else
            {
                current=current.next;
            }
        }
        return fakehead.next;

        
    }
}

 建立虚拟头指针fakehead,用空构造函数建造就可以,将fakehead的next指向head

用current指向fakehead开始遍历链表,从head开始进行判断,cur的next的val值和提供的目标值一样就进行移除操作,否则移动指针指向cur的next指针。


707设计链表中等题

这道题非常考察链表的基本操作,沿用203题,为了进行单链表的统一操作,本题用虚拟头结点 

class MyLinkedList {

    //构建链表ListNode
    class ListNode{
        int val;
        ListNode next;
        ListNode(int val)
        {
            this.val=val;
        }

    }
    //建立虚拟头结点
    private ListNode fakehead;

    //记录链表总长度
    private int nodelen;

    public MyLinkedList() {
        this.fakehead=new ListNode(0);
        this.nodelen=0;

    }


    
    public int get(int index) {
        //查找下标为index的val
        if(index<0 || index>=nodelen)
        {
            return -1;
        }
        ListNode current=fakehead;
        //找到index+1
        for(int i=0;i<=index;i++)
        {   
            current=current.next;
         
        }
        return current.val;

    }
    
    public void addAtHead(int val) {
        //虚拟头指针后面增加一个元素
        ListNode newnode=new ListNode(val);
        newnode.next=fakehead.next;
        fakehead.next=newnode;
        nodelen++;

        
    }
    
    public void addAtTail(int val) {
        //因为要在尾巴插入,所以要记录链表的总长度
        ListNode newnode=new ListNode(val);
        ListNode current=fakehead;
        while(current.next!=null)
        {
            current=current.next;
        }
        //现在指向最后的元素了
        current.next=newnode;
        nodelen++;
        
    }
    
    public void addAtIndex(int index, int val) {
        if(index<0 || index>nodelen)
        {
            return;
        }
        ListNode newnode=new ListNode(val);
        ListNode current=fakehead;
        //插入到index前面
        for(int i=0;i<index;i++)
        {
            current=current.next;
        }
        newnode.next=current.next;
        current.next=newnode;        
        nodelen++;        
    }
    
    public void deleteAtIndex(int index) {
        if(index<0 ||index>=nodelen)
        {
            return;
        }
        ListNode current=fakehead;
        for(int i=0;i<index;i++)
        {
            current=current.next;
        }
        current.next=current.next.next;
        nodelen--;
        
    }
}
  • 首先为了初始化链表,我们需要写一个链表类,然后定义两个成员变量fakehead(虚拟头指针)和nodelen(链表中元素的个数),初始化的时候fakehead定义为val为0的链表元素,nodelen为0
  • 根据索引index去get一个元素的val值,首先要判断index是不是小于0或者大于等于nodelen(当前的元素值索引最大只能是nodelen-1),然后从i=0遍历到index+1就可以,因为是从虚拟头结点开始遍历的
  • 在第一个元素添加很简单,就是虚拟头指针原来的next变为新添加元素的next,虚拟头指针的next指向新添加元素就可以了
  • 在尾部添加元素,只需要一直遍历指针指向最后一个元素然后next设为新添加元素
  • 给定索引index和val,在index元素的前面插入新元素,我们需要找到前置链表元素的位置,然后进行添加操作,用for循环遍历的时候,就需要遍历到index-1下标的元素位置


206反转链表简单题

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
        //一次翻转,用双指针,从头开始遍历
        ListNode pre=null;
        ListNode cur=head;

        //交换用
        ListNode temp=null;
        //前置指针先指向null
        while(cur!=null)
        {
            temp=cur.next;
            cur.next=pre;
            pre=cur;
            cur=temp;
        }
        return pre;

        
    }
}

双指针思想,设置pre为前置指针,让cur一直指向pre,就相当于反转了链表

注意:pre循环的时候要指向cur,而cur为了能指向本来的next,需要建立一个链表指针temp来保存


24两两交换链表中的节点 中等

虚拟头指针+两个temp链表进行交换

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode swapPairs(ListNode head) {
        //建立一个虚拟头指针
        ListNode fake=new ListNode();
        fake.next=head;

        ListNode cur=fake;
        ListNode temp1=new ListNode();
        ListNode temp2=new ListNode();
        while(cur.next!=null && cur.next.next!=null)
        {
            //满足交换条件
            temp1=cur.next;
            temp2=cur.next.next.next;
            //f-c
            cur.next=cur.next.next;
            //f-2-1
            cur.next.next=temp1;
            //f-2-1-3
            cur.next.next.next=temp2;
            
            cur=temp1;
        }

        return fake.next;        
    }
}

19删除链表的倒数第N个节点 中等


/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        //虚拟头指针
        ListNode fake=new ListNode();
        fake.next=head;

        //设置双指针
        ListNode slow=fake;
        ListNode fast=fake;

        //先让fast移动到第n个位置
        for(int i=0;i<n;i++)
        {
            fast=fast.next;
        }
        //再两个一起移动
        while(fast.next!=null)
        {
            fast=fast.next;
            slow=slow.next;
        }
        //删除slow后面的节点
        slow.next=slow.next.next;
        return fake.next;
        
    }
}

 

用快慢双指针完成这个问题,虚拟头指针方便统一操作,slow的下一个指标对应的元素就是要删除的元素 

142环形链表

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        //检查有没有环,快慢指针,快指针移动两个元素,慢指针一次移动一个元素,如果有环一定会相遇
        ListNode fast=head;
        ListNode slow =head;

        while(fast!=null && fast.next!=null)
        {
            slow=slow.next;
            fast=fast.next.next;

            if(slow==fast)
            {
                //相遇了,记录相遇节点
                ListNode index1=slow;
                //设入口到head距离为x,环入口到相遇节点为y,相遇节点到入口的节点数是z
                //则有2(x+y)=x+y+n(y+z)等价于x=n(y+z)-y等价于x=(n-1)(y+Z)+z
                //由于n至少转了一圈以上,fast才能够追上slow,所以只要一个指针从head出发,一个指针从相遇节点出发,最终相遇的地方就是环的路口
                ListNode index0=head;

                while(index0!=index1)
                {
                    index0=index0.next;
                    index1=index1.next;
                }
                return index0;
            }
        }
        return null;
        
    }
}
  1.  快慢指针入手,快指针每次移动两个下标,慢指针每次移动一个,如果有环,必定相遇,由于快指针每次移动两个,所以while循环的条件是他现在和next都不为null
  2. 如何判断出口,就要用数学公式进行判断,根据相遇的时候,快指针移动节点的个数是慢指针移动节点个数的二倍,列出等价公式,得到x=(n-1)(y+z)+z
  3. 这说明从相遇节点出发无论快指针是走了一圈y+z的路程还是很多圈,最终都会和从head出发的指针相遇,而这个相遇的地点就是环的入口指针
  4. xyz示意图

 

 

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

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

相关文章

【ARM】MDK浏览信息的生成对于构建时间的影响

1、 文档目标 用于了解MDK的代码浏览信息的生成对于工程的构建是否会产生影响。 2、 问题场景 客户在MDK中使用Compiler 5对于工程进行构建过程中发现&#xff0c;对于是否产生浏览信息会对于构建时间产生一定的影响。在Options中Output栏中勾选了Browse Information后&#…

py爬虫的话,selenium是不是能完全取代requests?

selenium适合动态网页抓取&#xff0c;因为它可以控制浏览器去点击、加载网页&#xff0c;requests则比较适合静态网页采集&#xff0c;它非常轻量化速度快&#xff0c;没有浏览器开销&#xff0c;占用资源少。当然如果不考虑资源占用和速度&#xff0c;selenium是可以替代requ…

docker B站学习

镜像是一个只读的模板&#xff0c;用来创建容器 容器是docker的运行实例&#xff0c;提供了独立可移植的环境 https://www.bilibili.com/video/BV11L411g7U1?spm_id_from333.788.videopod.episodes&vd_sourcee60c804914459274157197c4388a4d2f&p3 目录挂载 尚硅谷doc…

SpringBoot高校宿舍信息管理系统小程序

概述 基于SpringBoot的高校宿舍信息管理系统小程序项目&#xff0c;这是一款非常适合高校使用的信息化管理工具。该系统包含了完整的宿舍管理功能模块&#xff0c;采用主流技术栈开发&#xff0c;代码结构清晰&#xff0c;非常适合学习和二次开发。 主要内容 这个宿舍管理系…

ICASSP2025丨融合语音停顿信息与语言模型的阿尔兹海默病检测

阿尔兹海默病&#xff08;Alzheimers Disease, AD&#xff09;是一种以认知能力下降和记忆丧失为特征的渐进性神经退行性疾病&#xff0c;及早发现对于其干预和治疗至关重要。近期&#xff0c;清华大学语音与音频技术实验室&#xff08;SATLab&#xff09;提出了一种将停顿信息…

LabVIEW杂草识别与精准喷洒

基于LabVIEW构建了一套集成机器视觉、智能决策与精准控制的农业杂草识别系统。通过高分辨率视觉传感器采集作物图像&#xff0c;利用 LabVIEW 的 NI Vision 模块实现图像颜色匹配与特征分析&#xff0c;结合 Arduino 兼容的工业级控制硬件&#xff0c;实现杂草定位与除草剂精准…

学习日记-day20-6.1

完成目标&#xff1a; 知识点&#xff1a; 1.集合_Collections集合工具类 方法:static <T> boolean addAll(Collection<? super T> c, T... elements)->批量添加元素 static void shuffle(List<?> list) ->将集合中的元素顺序打乱static <T>…

【音视频】 FFmpeg 解码H265

一、概述 实现了使用FFmpeg读取对应H265文件&#xff0c;并且保存为对应的yuv文件 二、实现流程 读取文件 将H265/H264文件放在build路径下&#xff0c;然后指定输出为yuv格式 在main函数中读取外部参数 if (argc < 2){fprintf(stderr, "Usage: %s <input file&…

软件测试|FIT故障注入测试工具——ISO 26262合规下的智能汽车安全验证引擎

FIT&#xff08;Fault Injection Tester&#xff09;是SURESOFT专为汽车电子与工业控制设计的自动化故障注入测试工具​&#xff0c;基于ISO 26262等国际安全标准开发&#xff0c;旨在解决传统测试中效率低、成本高、安全隐患难以复现的问题&#xff0c;其核心功能包括&#xf…

3D拟合测量水杯半径

1&#xff0c;目的。 测量水杯的半径 如图所示&#xff1a; 2&#xff0c;原理。 对 3D 点云对象 进行圆柱体拟合&#xff0c;获取拟合后的半径。 3&#xff0c;注意事项。 在Halcon中使用fit_primitives_object_model_3d进行圆柱体拟合时&#xff0c;输出的primitive_para…

Python训练打卡Day38

Dataset和Dataloader类 知识点回顾&#xff1a; Dataset类的__getitem__和__len__方法&#xff08;本质是python的特殊方法&#xff09;Dataloader类minist手写数据集的了解 在遇到大规模数据集时&#xff0c;显存常常无法一次性存储所有数据&#xff0c;所以需要使用分批训练的…

Selenium基础操作方法详解

Selenium基础操作方法详解&#xff1a;从零开始编写自动化脚本&#xff08;附完整代码&#xff09; 引言 Selenium是自动化测试和网页操作的利器&#xff0c;但对于新手来说&#xff0c;掌握基础操作是成功的第一步。本文将手把手教你使用Selenium完成浏览器初始化、元素定位、…

简单三步FastAdmin 开源框架的安装

简单三步FastAdmin 开源框架的安装 第一步&#xff1a;新建站点1&#xff0c;在宝塔面板中&#xff0c;创建一个新的站点&#xff0c;并填写项目域名。 第二步&#xff1a;上传框架1&#xff0c;框架下载2&#xff0c;上传解压缩 第三步&#xff1a;配置并安装1&#xff0c;进入…

RISC-V 开发板 MUSE Pi Pro 搭建 Spacengine AI模型部署环境

视频讲解&#xff1a; RISC-V 开发板 MUSE Pi Pro 搭建 Spacengine AI模型部署环境 Spacengine 是由 进迭时空 研发的一套 AI 算法模型部署工具&#xff0c;可以方便的帮助用户部署自己的模型在端侧&#xff0c; 环境部署的方式&#xff0c;官方提供了两种方式&#xff1a; do…

【Unity】AudioSource超过MaxDistance还是能听见

unity版本&#xff1a;2022.3.51f1c1 将SpatialBlend拉到1即可 或者这里改到0 Hearing audio outside max distance - #11 by wderstine - Questions & Answers - Unity Discussions

Qt 读取和写入 INI 格式的配置文件

Qt 读取和写入 INI 格式的配置文件 前言&#xff1a;INI 配置文件在 Qt 开发中的重要性基础夯实&#xff1a;INI 文件结构与 QSettings 核心概念1. INI 文件的基本结构2. QSettings 类概述3. 初始化 QSettings 对象4. 基本读写操作5. 高级操作技巧5.1 处理数组和列表5.2 检查键…

Spring:从青铜到王者,你的Java修炼手册

一、Spring家族宇宙&#xff1a;原来你是这样的框架&#xff08;青铜段位&#xff09; 1.1 Spring的"前世今生"&#xff1a;从泡面到满汉全席 ​​2002年的泡面哲学​​&#xff1a;Rod Johnson在厨房煮泡面时突然顿悟&#xff1a;"Java开发为什么不能像泡面一…

Qt creator 设计页面控件认识与了解

记录一下 Qt 中的认识与了解&#xff1a; 在 Qt 中&#xff0c;这些功能属于 Qt Designer 的组件过滤系统&#xff0c;旨在帮助开发者在对象浏览器中快速定位和使用不同类型的控件和组件。以下是每个功能的详细讲解&#xff1a; ‌Layouts&#xff08;布局&#xff09;‌&…

NVIDIA Mellanox BlueField-2 DPU(Data Processing Unit)智能网卡的调试和使用

专有名词 OOB&#xff1a; BMC&#xff1a; BFB&#xff1a; EMMC&#xff1a; 关键词解释eMMCEmbedded Multi-Media Card——把 NAND 闪存颗粒与控制器封装在一起的板载存储件&#xff0c;类似手机里的“内置储存” .deb&#xff1a;文件是​​Debian软件包格式​​的专…

Tomcat- AJP协议文件读取/命令执行漏洞(幽灵猫复现)详细步骤

一、漏洞描述 Apache Tomcat是由Apache软件基金会属下Jakarta项目开发的Servlet容器.默认情况下,Apache Tomcat会开启AJP连接器,方便与其他Web服务器通过AJP协议进行交互.但Apache Tomcat在AJP协议的实现上存在漏洞,导致攻击者可以通过发送恶意的AJP请求,可以读取或者包含Web应…