Skip to main content

19. 删除链表的倒数第N个节点 [medium]

19. 删除链表的倒数第N个节点 [medium]

https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/

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

示例:

给定一个链表: 1->2->3->4->5, 和 n = 2.

当删除了倒数第二个节点后,链表变为 1->2->3->5.

说明:

  • 给定的 n 保证是有效的。

进阶:

  • 你能尝试使用一趟扫描实现吗?

通过次数191,668 | 提交次数492,349

Second Try

2020-07-07

看了题解才知道还有双指针法,双指针法在链表里算是常见的技巧了,没接触过很难想到,接触了就会觉得巧妙。

倒数n个元素,谁能想到开两个起点指针,其中一个先走个n步,然后两个指针再一起走(注意这时候两个指针之间间隔为n),第一个到达结尾的时候,上一个指针刚好在倒数n + 1的位置。

# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None

class Solution(object):
def removeNthFromEnd(self, head, n):
"""
:type head: ListNode
:type n: int
:rtype: ListNode
"""
dummy = ListNode(None)
dummy.next = head
first = second = dummy
c = 0
while first.next and c < n:
first = first.next
c += 1
while first.next:
second = second.next
first = first.next
second.next = second.next.next
return dummy.next
  • 执行用时:16 ms, 在所有 Python 提交中击败了97.40%的用户
  • 内存消耗:12.7 MB, 在所有 Python 提交中击败了9.09%的用户

First Try

2020-07-06

一波扫描,那就得牺牲一些空间来缓存吧。

另外有两个特殊条件需要考虑,一是整体被删没了,二是head也被删没了。

class Solution(object):
def removeNthFromEnd(self, head, n):
"""
:type head: ListNode
:type n: int
:rtype: ListNode
"""
# 写第一波的时候,又没考虑好边界条件: [1] 1
reserve = [head] # n + 1
node = head
while node.next:
node = node.next
reserve.append(node)
if len(reserve) > n + 1:
reserve.pop(0)

# 全删没了
if n == 1 and len(reserve) == 1:
return None
# 前面删没了
if len(reserve) == n:
return reserve[1]
# 正常部分, len(reserve) = n + 1
reserve[0].next = reserve[1].next
return head
  • 执行用时:28 ms, 在所有 Python 提交中击败了47.51%的用户
  • 内存消耗:12.8 MB, 在所有 Python 提交中击败了9.09%的用户