题目:给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
如 1 2 3 4 5 删除倒数第 2 个节点 返回 1 2 3 5
(你能尝试使用一趟扫描实现吗?)
思路:
两次遍历:(不符合要求)
先求列表长度,再进行删除
一次遍历:(快慢指针)
因为给定的是 倒数的点的 下标,所以要反着来思考 1→2→3→4→5
① n:代表了要删除点(4)倒数的位置
② 如果我们设置两个指针 p指向3 q指向null 她们之间差的n个元素分别是4 5 1→2→3→4→5→null。 找到了p q让p = p.next即可
③ 所以最开始可以保持p q两指针的距离进行遍历
1→2→3→4→5→null p指向1 q指向4
ps:有一个问题
① 1→2→3→null n=2 可行
p q
② 但是 1→2→3→null n=3
p q(此时q等于null的next)
则不合理,所以在将 q 后移的过程中要判断 q是否为空 如果为空,则代表其删除的是第一个,直接返回 head.next即可。
复杂度:时间复杂度 O(n) 空间复杂度 O(1)
代码:
def removeNthFromEnd(head, n):
p1, p2 = head, head
if not p2:
return head
# 1→2→3→4→5→null
# p q
while n:
# 当删除的是开头的值时 p2会空 1 → 2 → null n=2
if not p2:
return p1.next
p2 = p2.next
n -= 1
while p2:
p1, p2 = p1.next, p2.next
p1.next = p1.next.next
return head