首页 > 其他分享 >【LeetCode链表#10】删除链表中倒数第n个节点(双指针)

【LeetCode链表#10】删除链表中倒数第n个节点(双指针)

时间:2023-01-18 11:11:06浏览次数:67  
标签:10 slow fast next 链表 节点 LeetCode 指针

删除链表倒数第N个节点

力扣题目链接(opens new window)

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

进阶:你能尝试使用一趟扫描实现吗?

示例 1:

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

输入:head = [1,2,3,4,5], n = 2 输出:[1,2,3,5] 示例 2:

输入:head = [1], n = 1 输出:[] 示例 3:

输入:head = [1,2], n = 1 输出:[1]

思路

最开始我是想先把链表翻转,然后遍历到第n个节点,将其删除,然后再把链表翻转并返回

这么做显然提升了代码复杂度,以至于我并没有写出逻辑正常的代码,并且我估计写出来也超时了

参考删除第n个链表节点的操作

我们可以发现:要删除某个节点,当前指针cur必须指向待删除节点的前一个节点

这样,通过将cur指向下一个节点的下一个节点就可以把待删除节点移除

明确了删除方式之后,那么如何找到倒数第n个节点?

这里需要引入双指针思想,分别定义快慢指针指向dummy

快指针fast先移动n步

然后快慢指针一起向后移动,直到快指针指向null

此时,slow指向的就是倒数第n个节点

但是根据删除节点的操作,现在的情况我们是删不了slow指向的节点的,只能删除下一个

即慢指针slow要指向待删除节点的前一个

所以快指针fast应该先走n+1步

代码
class Solution {
    
    public ListNode removeNthFromEnd(ListNode head, int n) {
        //双指针法
        //创建dummy
        ListNode dummy = new ListNode(0);
        dummy.next = head;

        //快慢指针指向dummy
        ListNode fast = dummy;
        ListNode slow = dummy;

        n++;//让fast走n+1步
        for(int i = n; i > 0; i--){
            if(fast == null){//避免走着走着到链表尾部的情况
                break;
            }
            fast = fast.next;
        }

        //快慢指针一起移动
        while(fast != null){
            fast = fast.next;
            slow = slow.next;
        }
        //注意删除操作
        slow.next = slow.next.next;
        return dummy.next;

    }
}
易错点

1、为了让慢指针落在待删除节点前,快指针需要先走n+1步

并且不能写成:

for(int i = n; i > 0; i--){
            if(fast == null){//避免走着走着到链表尾部的情况
                break;
            }
            fast = fast.next;
        }
fast = fast.next;

因为如果n大于链表长度,那之后就相当于对空指针进行操作了

2、删除操作

删除操作是

slow.next = slow.next.next;//让待删除节点直接等于它之后的一个节点,即代替掉要删除的节点

而不是

slow = slow.next.next;//移动slow到它的下下一个位置

标签:10,slow,fast,next,链表,节点,LeetCode,指针
From: https://www.cnblogs.com/DAYceng/p/17059430.html

相关文章