删除链表的倒数第N个结点(LeetCode)
题目
给你一个链表,删除链表的倒数第个结点,并且返回链表的头结点。
示例1:输入:,
输出:
示例2:
输入:,
输出:
示例3:输入:,
解题
class ListNode:def __init__(self, val=0, next=None):self.val = valself.next = nextclass Solution:def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:# 虚拟头结点dummy = ListNode(0)dummy.next = head# 删除倒数第 n 个节点,先找到倒数第 n + 1 个节点x = self.findFromEnd(dummy, n + 1)# 删掉倒数第 n 个节点x.next = x.next.nextreturn dummy.next# 返回链表的倒数第 k 个节点@staticmethoddef findFromEnd(head: ListNode, k: int) -> ListNode:p1 = head# p1 先走 k 步for _ in range(k):p1 = p1.nextp2 = head# p1 和 p2 同时走,直到 p1 到达链表末尾while p1:p2 = p2.nextp1 = p1.next# p2 现在指向倒数第 k 个节点return p2def print_linked_list(head: ListNode):"""打印链表中的所有节点值"""current = headwhile current:print(current.val, end=" -> " if current.next else "\n")current = current.nextdef list_to_linked_list(values):"""将列表转换为链表"""if not values:return Nonedummy = ListNode(0)current = dummyfor value in values:current.next = ListNode(value)current = current.nextreturn dummy.nextdef linked_list_to_list(head: ListNode):"""将链表转换为列表"""result = []current = headwhile current:result.append(current.val)current = current.nextreturn result# 测试代码
if __name__ == "__main__":# 测试案例test_cases = [([1, 2, 3, 4, 5], 2, [1, 2, 3, 5]), # 删除倒数第二个节点([1], 1, []), # 删除唯一节点([1, 2], 1, [1]), # 删除尾节点([1, 2], 2, [2]), # 删除头节点([1, 2, 3], 3, [2, 3]), # 删除头节点(倒数第三个)]for i, (values, n, expected) in enumerate(test_cases):head = list_to_linked_list(values)solution = Solution()print(f"测试用例 {i + 1}: 原链表:", end="")print_linked_list(head)new_head = solution.removeNthFromEnd(head, n)result = linked_list_to_list(new_head)print(f"删除倒数第 {n} 个节点后:", end="")print_linked_list(new_head)assert result == expected, f"测试失败:期望 {expected}, 但得到 {result}"print("测试通过\n")
测试用例 1: 原链表:1 -> 2 -> 3 -> 4 -> 5
删除倒数第 2 个节点后:1 -> 2 -> 3 -> 5
测试通过测试用例 2: 原链表:1
删除倒数第 1 个节点后:测试通过测试用例 3: 原链表:1 -> 2
删除倒数第 1 个节点后:1
测试通过测试用例 4: 原链表:1 -> 2
删除倒数第 2 个节点后:2
测试通过测试用例 5: 原链表:1 -> 2 -> 3
删除倒数第 3 个节点后:2 -> 3
测试通过