Leetcode Link: 剑指 Offer II 021. 删除链表的倒数第 n 个结点 - 力扣(LeetCode) (leetcode-cn.com) 剑指 Offer 22. 链表中倒数第k个节点 - 力扣(LeetCode)

题目

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

解法一

思路:两次遍历,第一次遍历长度,第二次找到对应的需要删除的节点

题解:略

解法二

思路:同向快慢指针,快指针提前启动 n 步后,再启动慢指针。

题解:

'''Version 0'''
class Solution:
	def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
 
		step = 0
		slow = head
		fast = head
		count = 0
 
		while(fast.next):
			fast = fast.next
			step = step + 1
			count = count + 1
			# 这里大于n+1的原因是为了让慢指针指向打算删除节点的前一个节点,然后直接.next=.next.next就可以
			if step >= n+1: 
				slow = slow.next
		# 出现恰好删除头节点的情况时处理办法
		if count == n - 1:
			return head.next
		# 删除对应节点
		slow.next = slow.next.next
 return head

上代码中,由于每次都需要对头节点判空,造成了头节点和其他节点的逻辑上的不一致性,同时增加了代码量,好的处理方法是增加一个空的头节点,即哨兵。

class Solution:
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
		# 添加伪头节点,并与原头节点连接
        dummy = ListNode()
        dummy.next = head
 
        step = 0
        fast = dummy
        slow = dummy
 
        while(fast.next):
            fast = fast.next
            step = step + 1
            if step >= n+1:
                slow = slow.next
 
        slow.next = slow.next.next
        # 注意这里返回的时候不要返回伪头节点
        # 也最好不要直接返回head,无法处理 [1], 1 的输入
        return dummy.next

启发和联系