链表5:删除链表的倒数第N个结点(19)
本题如下:(链接:https://leetcode.cn/problems/remove-nth-node-from-end-of-list/)
题目:给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

思路:
这道题是双指针的经典应用,如果要删除倒数第n个节点,让fast移动n步,然后让fast和slow同时移动,直到fast指向链表末尾。删掉slow所指向的节点就可以了。过程虽然不复杂,但要注意一些细节。
主要分为如下几步:
(1)首先这里推荐使用虚拟头结点,这样方便处理删除实际头结点的逻辑。
(2)定义fast指针和slow指针,初始值为虚拟头结点,如下图所示:

(3)fast首先走n + 1步 ,为什么是n+1呢,因为只有这样同时移动的时候slow才能指向删除节点的上一个节点(方便做删除操作),如下图所示:

(4)fast和slow同时移动,直到fast指向末尾,如下图所示:

(5)删除slow指向的下一个节点,如下图所示:

这样就可以比较清晰地写出如下的C++代码:
1 class Solution { 2 public: 3 ListNode* removeNthFromEnd(ListNode* head, int n) { 4 ListNode* dummyHead = new ListNode(0); 5 dummyHead->next = head; 6 ListNode* slow = dummyHead; 7 ListNode* fast = dummyHead; 8 while(n-- && fast != NULL) { 9 fast = fast->next; 10 } 11 fast = fast->next; // fast再提前走一步,因为需要让slow指向删除节点的上一个节点 12 while (fast != NULL) { 13 fast = fast->next; 14 slow = slow->next; 15 } 16 slow->next = slow->next->next; 17 return dummyHead->next; 18 } 19 };
同时给出相应的Java版本:
1 class Solution { 2 public ListNode removeNthFromEnd(ListNode head, int n) { 3 ListNode dummy = new ListNode(-1); 4 dummy.next = head; 5 6 ListNode slow = dummy; 7 ListNode fast = dummy; 8 while (n-- > 0) { 9 fast = fast.next; 10 } 11 // 记住 待删除节点slow 的上一节点 12 ListNode prev = null; 13 while (fast != null) { 14 prev = slow; 15 slow = slow.next; 16 fast = fast.next; 17 } 18 // 上一节点的next指针绕过 待删除节点slow 直接指向slow的下一节点 19 prev.next = slow.next; 20 // 释放 待删除节点slow 的next指针, 这句删掉也能AC 21 slow.next = null; 22 23 return dummy.next; 24 } 25 }
本文来自博客园,作者:Ricentch,转载请注明原文链接:https://www.cnblogs.com/cnwsh/p/16575998.html

浙公网安备 33010602011771号