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

删除链表的倒数第N个节点 力扣19

一、题目

给你一个链表,删除链表的倒数第 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]

二、思路

           1.容易想到的思路就是先遍历一遍链表统计长度,倒数第n个节点就是正数的第len - n + 1个节点。要删除该节点,我们要找到len - n的节点,即可删除。

            2.经典思路:删除倒数第n个节点,让fast移动n步,然后让fast和slow同时移动,直到fast指向链表末尾。删掉slow所指向的节点就可以了。为了统一头节点和其他节点的删除操作,使用虚拟头节点。

三、代码

        暴力解:

public class Test {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入链表的元素,输入非数字结束:");
        ListNode head = new ListNode(sc.nextInt());
        ListNode current = head;
        while (sc.hasNextInt()) {
            ListNode node = new ListNode(sc.nextInt());
            current.next = node;
            current = current.next;

        }
        ListNode listNode = removeNthFromEnd(head, 2);
        //打印链表
        current = listNode;
        while (current != null) {
            System.out.print(current.val + " ");
            current = current.next;
        }

    }

    public static ListNode removeNthFromEnd(ListNode head, int n) {
        //暴力法
        //先统计链表长度,找到该节点的前一个节点即可,倒数第n个节点是正数的第(len-n+1)个节点
        int len = 0;
        ListNode cur = head;
        while (cur != null) {
            len++;
            cur = cur.next;
        }
        //如果只有一个元素
        if(len == 1){
            return null;
        }
        // 如果需要删除头节点
        if (len - n == 0) {
            return head.next;
        }

        cur = head;
        //找到第len-n+1个节点的前一个节点
        for (int i = 1; i < len - n; i++) {
            cur = cur.next;
        }
        cur.next = cur.next.next;
        return head;
    }
}

       双指针法:

        

class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
        //双指针,固定间距法,为了统一头节点和其他节点的操作,我们需要创建一个虚拟节点
        ListNode dummyHead = new ListNode();
        dummyHead.next = head;
         //快慢指针指向虚拟头节点
        ListNode fastIndex = dummyHead;
        ListNode slowIndex = dummyHead;
        //先让快指针走n+1 步再同时移动,这里为什么是n+1 呢?
        //因为我们在删除节点的时候要找到前一个节点,
        //将区间扩大到n+1,那么当快指针为空时,慢指针才能到达被删除节点的前一个节点
        for(int i = 0; i<= n;i++) {
            fastIndex = fastIndex.next;
        }
        while(fastIndex != null) {  //快慢指针同时移动
            fastIndex = fastIndex.next;
            slowIndex = slowIndex.next;
        }
         // 检查 slowIndex.next 是否为 null,以避免空指针异常
        if (slowIndex.next != null) {
            slowIndex.next = slowIndex.next.next;
        }
        return dummyHead.next;
    }
}

相关文章:

  • 【Linux笔记】基础IO(上)
  • 【MySQL】第十二弹---表连接详解:从内连接到外连接
  • Spark的数据本地性是在哪个环节确定的
  • MongoDB分片集群
  • 第三阶段-产品方面的技术疑难
  • GMAC网络延时性能优化
  • office集成deepseek插件,office集成deepseek教程(附安装包)
  • 人工智能训练物理模拟器 MuJoCo入门教程 常用函数介绍及测试用例
  • 基于 DataEase 的企业数据分析实践
  • centos7操作系统下安装docker,及查看docker进程是否启动
  • 如何用 DeepSeek 和 ChatGPT 打造智能搜索与问答体验
  • 残差收缩模块
  • 大数据测试中,数据仓库表类型有哪些?
  • 深度学习中关于超参数的解释
  • vm+centos虚拟机
  • Kotlin中RxJava用法
  • SQL 中为什么参数多了not in 比 in 慢多了,怎么优化
  • JavaScript系列05-现代JavaScript新特性
  • .NET10 - 预览版1新功能体验(一)
  • Generalized Sparse Additive Model with Unknown Link Function
  • 2025世界数字教育大会将于5月14日至16日在武汉举办
  • 上海:下调个人住房公积金贷款利率
  • 长安汽车辟谣作为二级企业并入东风集团:将追究相关方责任
  • 诺和诺德一季度减重版司美格鲁肽收入增83%,美国市场竞争激烈下调全年业绩预期
  • 上海乐高乐园度假区将于7月5日开园
  • 默茨在第二轮投票中当选德国总理