删除链表的倒数第N个节点

151 阅读1分钟

leetcode原题 删除链表的倒数第N个节点

一开始想到的笨方法是:

  1. 把所有节点入栈
  2. 然后出栈N+1个,把N+1个的next指向第N-1个。
  3. 需要的空间复杂度为O(n)
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        node = head
        stack = []
        while node:
            print(node.val)
            stack.append(node)
            node = node.next
        if stack[-n] is stack[0]:
            if len(stack) > 1:
                head = stack[1]
            else:
                return None
        else:
            if n != 1:
                stack[-n-1].next = stack[-n+1]
            else:
                stack[-2].next = None
        return head

双指针的思路

  1. 快指针先走N步,然后快指针和慢指针一步一步地走。
  2. 当快指针走到结尾的时候,慢指针指向的地方就是该删除的节点。
  3. 这里多用一个pre指针,记录慢指针前一个节点,方便删除操作。
  4. 空间复杂度为O(1)
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        fast = head
        slow = head
        pre = slow
        while n:
            fast = fast.next
            n -= 1
        
        while fast:
            print(fast.val, slow.val)
            pre = slow
            fast = fast.next
            slow = slow.next
            
        if pre is slow:
            head = slow.next
        else:
            pre.next = slow.next
        
        return head