看兔子如何删除单链表的倒数第 N 个结点

简介: 看兔子如何删除单链表的倒数第 N 个结点

看兔子如何删除单链表的倒数第 N 个结点

一、题目描述

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

image.pngimage.png

示例 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

二、思路分析

先从最简单的思路说起,想要知道倒数第几个节点的位置,首先要知道链表长度信息。

但是从题目信息,我们只得知这是一个单链表,并不知道它的长度信息。

这时候就可以考虑先遍历一遍链表的节点,统计一下链表的长度,然后再计算出节点在链表中的位置,这时候就用这个节点的前驱节点指向它的后继节点。

但是这里面有一个点要注意一下,如果删除的是头节点该怎么处理

代码实现

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        // 计算链表长度
        int length = 0;
        ListNode temp = head;
        while (temp != null) {
            ++length;
            temp = temp.next;
        }
        // 增加前置节点,防止删除第一个元素
        ListNode ans = new ListNode(0, head);
        temp = ans;
        // 计算出要删除节点在链表中的位置
        for (int i = 1; i < length - n + 1; i++) {
            temp = temp.next;
        }
        temp.next = temp.next.next;
        return ans.next;
    }
}

从代码实现中,我们可以看出空间复杂度为O(1),时间复杂度为O(n)

那么是不是还有更加优雅的方法呢?


小伙伴们,优雅的方法肯定是有的,就看你怎么理解这个了……

假设倒数第K个节点就是尾节点,那么我们只要把指针指向它的前驱节点即可,不需要在进行第二次扫描处理。

那么如何制造出倒数第K个节点就是尾节点的错觉呢?这就不的不请出两只小白兔了,假如在一条笔直笔直的小路上,我们让两只速度一样的小白兔赛跑,让其中的一只先跑K米,然后在再让另一只小白兔起跑……

那么请问一下,当先跑的那只小白兔到达终点的时候,另一个小白兔离终点还有多少米?

没错,这就是这题的关键思路,两只兔子解法~~~

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        if (head.next == null) {
            return null;
        }
        ListNode first = head;
        ListNode second = head;
        while (n > 0) {
            first = first.next;
            --n;
        }
        if (first == null) {
            return head.next;
        }
        while (first.next != null) {
            first = first.next;
            second = second.next;
        }
        second.next = second.next.next;
        return head;
    }
}

从代码实现中,我们可以看出空间复杂度为O(1),时间复杂度为O(n)

三、总结

关于链表的问题,基本上就是通过遍历链表解决问题,一次遍历不够就两次。此时我们可以使用空间换时间的策略,可以优先考虑是否能用多个指针,每个指针代表一次遍历,从而减少遍历的次数,提高查询效率。

目录
相关文章
|
1月前
|
算法
【❤️算法笔记❤️】-每日一刷-19、删除链表的倒数第 N个结点
【❤️算法笔记❤️】-每日一刷-19、删除链表的倒数第 N个结点
65 1
|
18天前
|
存储 算法 搜索推荐
链表的中间结点
【10月更文挑战第24天】链表的中间结点是链表操作中的一个重要概念,通过快慢指针法等方法可以高效地找到它。中间结点在数据分割、平衡检测、算法应用等方面都有着重要的意义。在实际编程中,理解和掌握寻找中间结点的方法对于解决链表相关问题具有重要价值。
10 1
|
2月前
链表的中间结点
链表的中间结点
178 57
|
1月前
Leetcode第十九题(删除链表的倒数第N个节点)
LeetCode第19题要求删除链表的倒数第N个节点,可以通过快慢指针法在一次遍历中实现。
40 0
Leetcode第十九题(删除链表的倒数第N个节点)
|
1月前
(剑指offer)18、删除链表的节点—22、链表中倒数第K个节点—25、合并两个排序的链表—52、两个链表的第一个公共节点(2021.12.07)
(剑指offer)18、删除链表的节点—22、链表中倒数第K个节点—25、合并两个排序的链表—52、两个链表的第一个公共节点(2021.12.07)
46 0
|
1月前
【LeetCode 09】19 删除链表的倒数第 N 个结点
【LeetCode 09】19 删除链表的倒数第 N 个结点
16 0
05_删除链表的倒数第N个节点
05_删除链表的倒数第N个节点
|
3月前
|
算法
LeetCode第19题删除链表的倒数第 N 个结点
该文章介绍了 LeetCode 第 19 题删除链表的倒数第 N 个结点的解法,通过使用快慢双指针,先将快指针移动 n 步,然后快慢指针一起遍历,直到快指针到达链尾,从而找到倒数第 N 个结点的前一个结点进行删除,同时总结了快慢指针可减少链表遍历次数的特点。
LeetCode第19题删除链表的倒数第 N 个结点
|
3月前
|
Python
【Leetcode刷题Python】剑指 Offer 22. 链表中倒数第k个节点
Leetcode题目"剑指 Offer 22. 链表中倒数第k个节点"的Python解决方案,使用双指针法找到并返回链表中倒数第k个节点。
52 5
|
4月前
【数据结构OJ题】链表中倒数第k个结点
牛客题目——链表中倒数第k个结点
37 1
【数据结构OJ题】链表中倒数第k个结点