Leetcode 删除链表倒数第 N 个节点

算法思想:

使用了双指针法。下面是详细的算法思想:

1. 引入虚拟头节点(dummy node)

  • 为了处理链表的一些边界情况(比如删除头节点),我们在链表的头部引入了一个虚拟节点 dummy,并让它指向原来的头节点 head。这样,无论我们要删除哪个节点,处理过程都变得更加统一和简单。

2. 定义两个指针:快指针(fast)和慢指针(slow)

  • 我们使用两个指针,fastslow,最初都指向虚拟头节点 dummy
  • 快指针 fast 会比慢指针 slow 超前移动 n+1 步。这样,当 fast 指向链表末尾(null)时,slow 刚好指向要删除节点的前一个节点。

3. 移动快指针

  • 首先,快指针 fast 先向前移动 n+1 步,这样可以确保快指针和慢指针之间相隔 n 个节点。

4. 同时移动快慢指针

  • 接下来,快慢指针一起向前移动,直到快指针到达链表的末尾。这时,慢指针 slow 就刚好处于要删除节点的前一个位置。

5. 删除节点

  • 现在,慢指针 slow 的下一个节点就是我们需要删除的节点。通过 slow.next = slow.next.next,我们跳过了这个节点,达到了删除的目的。

6. 返回新的头节点

  • 最后,返回 dummy.next。注意,链表的头节点可能发生了变化(如果原来的头节点被删除),因此我们返回虚拟节点 dummy 的下一个节点作为新的链表头节点。

代码核心思路总结:

  • 通过快慢指针法,仅需遍历链表一次(一次循环)就可以找到倒数第N个节点,并将其删除,时间复杂度为 O(L),其中 L 是链表的长度。空间复杂度为 O(1),因为只用了常数级别的额外空间。

示例分析:

假设输入链表为 [1, 2, 3, 4, 5]n = 2,即删除倒数第二个节点。

  1. 初始化fastslow 都指向虚拟节点 dummy
  2. 快指针前移fast 先向前移动 n+1 = 3 步,指向节点 3
  3. 同步移动:同时移动 fastslow,直到 fast 指向 null,此时 slow 指向节点 3 的前一个节点,即节点 2
  4. 删除节点:通过 slow.next = slow.next.next 删除节点 4,最终链表变为 [1, 2, 3, 5]

这样就成功地删除了倒数第2个节点。

在这里插入图片描述
java 实现代码:

/**
 * 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 dummyNode = new ListNode(0);
        dummyNode.next = head;

        ListNode slow = dummyNode; //dummyNode,slow,fast都是引用类型
        ListNode fast = dummyNode;

        for(int i = 0; i <= n; i++) { //快指针先移动 n+1 步
            fast = fast.next;
        }

        while(fast != null) { //然后快慢指针一起移动
            slow = slow.next;
            fast = fast.next;
        }
        
        slow.next = slow.next.next;
        return dummyNode.next;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值