返回
LeetCode 237:在删除链表节点时保持优雅
闲谈
2024-01-15 22:13:45
作为开发人员,我们经常需要在链表数据结构中添加或删除节点。特别是,删除链表节点 是一个经典问题,需要我们掌握扎实的链表基础和算法技巧。今天,我们将深入探讨 LeetCode 上的 237 题,探索如何优雅而高效地 完成此任务。
问题
给你一个链表的头节点 head
和一个节点 val
,请你删除链表中第一个 值为 val
的节点,并返回新的头节点。
提示:
- 链表中节点的值是唯一的。
- 不会存在两个值为
val
的节点。
优雅的解决方案
解决这个问题的优雅解决方案是使用双指针技术:
- 定义两个指针:
prev
指向当前节点的前驱节点,curr
指向当前节点。 - 初始化: 将
prev
设置为虚拟头节点(指向实际头节点之前),curr
设置为头节点。 - 遍历链表:
- 如果
curr
为空,则链表中不存在该节点,返回prev.next
(新的头节点)。 - 如果
curr.val
等于val
,则将prev.next
指向curr.next
,跳过curr
节点。 - 否则,将
prev
和curr
都向前移动一步。
- 如果
- 返回: 返回
prev.next
,这是新的头节点。
代码实现
def deleteNode(head: ListNode, val: int) -> ListNode:
prev = ListNode(0, head)
curr = head
while curr:
if curr.val == val:
prev.next = curr.next
break
else:
prev = curr
curr = curr.next
return prev.next
优化与变体
- 时间复杂度: O(n),其中 n 是链表的长度。我们必须遍历整个链表才能找到并删除节点。
- 空间复杂度: O(1),因为我们只使用了恒定的额外空间。
- 变体: 此算法还可以用于删除链表中的尾节点。在这种情况下,我们只需要一个指针(
curr
),并且在遍历到尾节点时将prev
指向null
。
总结
删除链表中的节点是链表编程中的一个基本操作。通过理解双指针技术,我们可以优雅高效地完成此任务。LeetCode 237 题提供了一个很好的机会来练习此技巧,并加深我们对链表数据结构的理解。通过持续的练习和创新,我们可以在算法和编程领域不断提升自己。