19. 删除链表的倒数第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]

题目链接:19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode) (leetcode-cn.com)

解题思路

暴力
  • 首先遍历整个单链表,计算出单链表的长度
  • 接着第二次遍历找到要删除节点位置的前一个节点,并将这个节点的next指向要删除节点的下一个节点,即p.next = p.next.next
  • 可以设置一个哑结点来方便删除头节点的操作
# 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)
        p = dummy
        # count记录节点的数量
        count = 0
        while p.next:
            count += 1
            p = p.next
        p = dummy
        for i in range(count-n):
            p = p.next
        p.next = p.next.next
        return dummy.next
双指针
  • 设置快慢两个指针 fastslow
  • 设置哑结点 dummy
  • 初始化两个指针都指向哑结点
  • 两个指针怎么走
    • 假设整个链表有 length 个节点
    • 首先先让快指针走 n + 1 步,快指针的目的地是链表末尾的空指针,此时快指针距离目的地还剩 length - n
    • 此时让快慢两个指针一起走
    • 当快指针走到目的地时,慢指针走到第 length - n 个节点,也就是倒数第 n - 1 个节点,慢指针指向要删除节点的前一个节点
# 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)
        fast = dummy
        slow = dummy
        for i in range(n+1):
            fast = fast.next
        while fast:
            fast = fast.next
            slow = slow.next
        slow.next = slow.next.next
        return dummy.next
posted on 2021-10-09 15:03  墩墩儿er  阅读(50)  评论(0)    收藏  举报