- 删除链表的倒数第 N 个结点(难度 中等)
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
示例 1:
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
示例 2:
输入:head = [1], n = 1
输出:[]
示例 3:
输入:head = [1,2], n = 1
输出:[1]
提示:
链表中结点的数目为 sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz
进阶:你能尝试使用一趟扫描实现吗?
题解
目前看到有三种方法
方法一:
算出链表长度,倒数n个删除,这个方法比较粗暴,不能一趟扫描完成。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
#虚拟节点
dummy=ListNode(next=head)
cur = dummy.next
count=0
while cur:
count+=1
cur=cur.next
cur = dummy
for _ in range(count-n):
cur=cur.next
cur.next=cur.next.next
return dummy.next
方法二:
post节点先走n步。prev再和post向后等到pos到链表尾,prev正好和post相隔n,pre到达倒数第n个节点的前一个:
class Solution:
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
dummy=ListNode(next=head)
prev=dummy
post=prev
#让post先走n步
while n>0:
post=post.next
n-=1
#这时post移到链尾,prev移到倒数第n个节点的前一个
while post.next:
prev=prev.next
post=post.next
prev.next=prev.next.next
return dummy.next
方法三:
回溯法,这个当时没想到,比较难想,代码简单明了。
class Solution:
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
if not head:
self.count = 0
return head
head.next = self.removeNthFromEnd(head.next, n) # 递归调用
self.count += 1 # 回溯时进行节点计数
return head.next if self.count == n else head