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

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

示例:

给定一个链表: 1->2->3->4->5, 和 n = 2.

当删除了倒数第二个节点后,链表变为 1->2->3->5.

说明:

给定的 n 保证是有效的。
进阶:
你能尝试使用一趟扫描实现吗?

方法1——计算长度

  1. # Definition for singly-linked list.
  2. # class ListNode:
  3. # def __init__(self, x):
  4. # self.val = x
  5. # self.next = None
  6. class Solution:
  7. def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
  8. length = 0
  9. cur = head
  10. while cur:
  11. length += 1
  12. cur = cur.next
  13. length = length-n
  14. cur = head
  15. l = 0
  16. if l == length:
  17. return head.next
  18. while l < length-1:
  19. cur = cur.next
  20. l += 1
  21. cur.next = cur.next.next
  22. return head

方法2——双指针

对法1的优化,让两个指针保持n的距离,并让其中一个指针到达第n个节点后同向移动,巧解本题。

  1. # Definition for singly-linked list.
  2. # class ListNode:
  3. # def __init__(self, x):
  4. # self.val = x
  5. # self.next = None
  6. class Solution:
  7. def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
  8. sentinel = ListNode(0)
  9. sentinel.next = head
  10. first, second = sentinel, head
  11. for i in range(n-1):
  12. second = second.next
  13. while second and second.next:
  14. first = first.next
  15. second = second.next
  16. first.next = first.next.next
  17. return sentinel.next