题目描述:
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:
给定的 n 保证是有效的。
进阶:
你能尝试使用一趟扫描实现吗?
思路:
方法一:两遍扫描,一次扫描求链表的长度,确定第二次扫描需要走过几个节点,注意一些边界情况
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
if not head:
return head
p = head
len_listNode = 0
# 求链表长度
while p:
len_listNode += 1
p = p.next
# 如果是删除第一个节点,直接返回第二个节点
if len_listNode == n:
return head.next
# 一直走到需要移除节点的上一个
p = head
for i in range(len_listNode - n - 1):
p = p.next
# 因为说过了 n 一定是合法的,所以p 一定不会指向最后一个节点
p.next = p.next.next
return head
方法二:一次扫描。想要删除倒数第 n 个,也就是整数第
l
e
n
(
n
o
d
e
l
i
s
t
)
−
n
+
1
len(nodelist) - n + 1
len(nodelist)−n+1 个,那么我们需要有一个指针指向第
l
e
n
(
n
o
d
e
l
i
s
t
)
−
n
len(nodelist) - n
len(nodelist)−n 个节点。使用快慢双指针,快指针先走 n 步,那么快慢指针之间相隔 n 个位置,之后快慢指针同时后移,当快指针指向尾结点时,慢指针刚好指向倒数第 n + 1 个节点。
class Solution:
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
p = q = head
# 快指针先走 n 步
for i in range(n):
q = q.next
# 如果快指针指向空了,说明需要删除头结点,直接返回
if not q:
return head.next
# 快慢指针同步后移,当快指针走到最后一个节点时,慢指针刚好指向要删除节点的前一个节点
while q.next:
p = p.next
q = q.next
p.next = p.next.next
return head