一往无前,披荆斩棘,路飞与剑指 Offer 18 携手共进!路飞_leetcode-剑指 Offer 18-删除链表的节点-链表删除实战剖析,算法精髓尽收眼底!
2024-01-15 04:48:09
SEO关键词:
剑指 Offer 18:披荆斩棘,删除链表节点
在算法的浩瀚海洋中,剑指 Offer 系列题目犹如璀璨的明珠,熠熠生辉。其中,第 18 道题目——“删除链表的节点”更是备受瞩目,可谓是检验算法功底的试金石。
本题看似简单,却暗藏玄机。题目要求我们,给定一个单向链表的头指针和一个要删除的节点的值,删除该节点并返回删除后的链表的头节点。
乍一看,这似乎轻而易举。然而,当我们深入思考时,就会发现其中蕴含着许多微妙之处。例如,如何高效地找到要删除的节点?如何确保删除操作不会破坏链表的完整性?如何处理特殊情况,如删除头节点或尾节点?
别担心,让我们逐一击破,共同踏上这场算法的冒险之旅!
算法思路:精准定位,巧妙删除
要删除链表中的指定节点,首先需要找到该节点的位置。一种朴素的方法是,从头节点开始遍历链表,逐个节点进行比较,直到找到要删除的节点。
然而,这种方法存在一个明显的缺陷:时间复杂度过高。链表的长度可能非常长,逐个节点遍历显然不是一个高效的解决方案。
为了提高效率,我们可以采用更巧妙的方法——利用链表节点之间的指针关系。具体来说,我们可以从头节点开始遍历链表,同时维护一个指向当前节点的前驱节点的指针。
当我们找到要删除的节点时,只需要修改前驱节点的指针,使其指向要删除节点的下一个节点即可。这样一来,就巧妙地完成了删除操作,而时间复杂度也降低到了 O(n),其中 n 为链表的长度。
代码实现:简洁优雅,一气呵成
有了算法思路,接下来就是将其转化为代码。为了让代码更具可读性和可维护性,我们采用面向对象的设计思想,将链表的结构和操作封装在一个类中。
class Node:
def __init__(self, val):
self.val = val
self.next = None
class LinkedList:
def __init__(self):
self.head = None
def insert_node(self, val):
new_node = Node(val)
if self.head is None:
self.head = new_node
else:
current = self.head
while current.next is not None:
current = current.next
current.next = new_node
def delete_node(self, val):
if self.head is None:
return None
if self.head.val == val:
self.head = self.head.next
return self.head
current = self.head
while current.next is not None:
if current.next.val == val:
current.next = current.next.next
return self.head
current = current.next
return self.head
# 测试代码
linked_list = LinkedList()
linked_list.insert_node(1)
linked_list.insert_node(2)
linked_list.insert_node(3)
linked_list.insert_node(4)
linked_list.insert_node(5)
print("原链表:")
current = linked_list.head
while current is not None:
print(current.val, end=" ")
current = current.next
print()
linked_list.delete_node(3)
print("删除节点后的链表:")
current = linked_list.head
while current is not None:
print(current.val, end=" ")
current = current.next
结语:算法之美,无处不在
剑指 Offer 18 这道题目,看似简单,却蕴含着深刻的算法思想。通过对链表结构和操作的深入理解,我们可以设计出高效优雅的解决方案。
算法之美,无处不在。它就像一门艺术,等待着我们去探索、去欣赏。愿每一位算法爱好者都能在算法的海洋中乘风破浪,勇往直前!