【LeetCode】19. 删除链表的倒数第 N 个结点
  TEZNKK3IfmPf 2024年03月29日 16 0

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

【LeetCode】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]

提示:

  • 链表中结点的数目为 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)

三、总结

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

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2024年03月29日 0

暂无评论

推荐阅读
  TEZNKK3IfmPf   2024年04月12日   18   0   0 算法leetcodeC++
  TEZNKK3IfmPf   2024年04月19日   20   0   0 leetcode位运算
TEZNKK3IfmPf