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

对于链表类题目,对某一个特定索引的元素进行操作往往会成为增加运算时间的瓶颈,因此如何通过尽可能少的遍历次数寻找到所要操作的元素就成为关键。
比如这道题,由于我们不知道链表的长度,并且只能从头部开始遍历,假设我们不运用任何技巧,两次遍历可以解决这个问题。
第一次遍历可以得知链表的长度L,第二次遍历从头找到L-n位置的链表元素,删除即可。
两次遍历,时间复杂度为O(n), 空间复杂度O(1)。
能不能用1次遍历解决这个问题呢?这里我们运用到解决这类线性列表的数据结构题目一个高频技巧,双指针。
为了方便,我们在原有链表前面设置一个哑结点,哑结点的好处在于,因为这里我们是要删除一个结点,所以我们可以定位到被删除结点的前置结点,然后将前置结点的后续指针指向被删除结点的后续结点,则可完成删除。
我们设置两个指针,两个指针初始状态都指向哑结点,指针fast 先走n步,然后指针fast和指针slow同步往前继续遍历链表,直至fast的后续结点为空,此时指针slow到达被删除结点的前置结点。
下面这个视频解释了这个过程:
超可爱!动画教你如何删除链表的倒数第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:
if not head:
return head
slownode = ListNode(None)
slownode.next = head
fastnode = slownode
for i in range(n):
fastnode = fastnode.next
while(fastnode.next!=None):
slownode = slownode.next
fastnode = fastnode.next
if slownode.next == head:
head = head.next
else:
slownode.next = slownode.next.next
return head
时间复杂度为O(n), 空间复杂度O(1)。
喜欢就点个赞吧~
本文介绍了一种仅需一次遍历的高效算法,用于解决链表中倒数第N个节点的删除问题。通过引入双指针技巧和哑结点,避免了两次遍历的时间开销,实现O(n)时间复杂度和O(1)空间复杂度。
1350

被折叠的 条评论
为什么被折叠?



