链表经典题攻略:反转、合并与环形链表
链表是数据结构中的一种,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。链表在计算机科学中应用广泛,特别是在实现动态数据结构时。本文将围绕链表这一主题,探讨LeetCode上的经典题目,包括链表反转、合并以及环形链表相关的题目,并提供相应的代码实现。
一、链表反转
链表反转是链表操作中最基础且常见的一个问题。它要求我们将链表的节点顺序颠倒,使得原本指向下一个节点的指针指向其前一个节点。
1.1 翻转单链表
以下是一个使用Python实现的单链表反转的示例代码:
python
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def reverse_single_list(head):
prev = None
current = head
while current:
next_node = current.next
current.next = prev
prev = current
current = next_node
return prev
1.2 翻转双向链表
双向链表与单链表类似,但每个节点都有一个指向前一个节点的指针。以下是一个反转双向链表的示例代码:
python
class DoublyListNode:
def __init__(self, val=0, prev=None, next=None):
self.val = val
self.prev = prev
self.next = next
def reverse_doubly_list(head):
prev = None
current = head
while current:
next_node = current.next
current.next = prev
current.prev = next_node
prev = current
current = next_node
return prev
二、链表合并
链表合并是将两个或多个链表合并成一个有序链表的过程。在LeetCode中,这类题目通常要求合并两个有序链表。
2.1 合并两个有序链表
以下是一个合并两个有序链表的示例代码:
python
def merge_two_lists(l1, l2):
dummy = ListNode()
tail = dummy
while l1 and l2:
if l1.val < l2.val:
tail.next = l1
l1 = l1.next
else:
tail.next = l2
l2 = l2.next
tail = tail.next
tail.next = l1 or l2
return dummy.next
2.2 合并K个有序链表
合并K个有序链表是一个更复杂的问题,可以使用分治法解决。以下是一个合并K个有序链表的示例代码:
python
def merge_k_lists(lists):
if not lists:
return None
while len(lists) > 1:
new_lists = []
for i in range(0, len(lists), 2):
l1 = lists[i]
l2 = lists[i + 1] if i + 1 < len(lists) else None
new_lists.append(merge_two_lists(l1, l2))
lists = new_lists
return lists[0]
三、环形链表
环形链表是一种特殊的链表,其中某个节点指向链表中的另一个节点,形成一个环。
3.1 检测环形链表
检测环形链表的关键是找到链表中是否存在环。以下是一个检测环形链表的示例代码:
python
def has_cycle(head):
slow = head
fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
return True
return False
3.2 删除环形链表中的环
删除环形链表中的环需要找到环的入口节点,并将其指向`None`。以下是一个删除环形链表中的环的示例代码:
python
def remove_cycle(head):
slow = head
fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
break
if slow != fast:
return head
slow = head
while slow.next != fast.next:
slow = slow.next
fast = fast.next
fast.next = None
return head
四、总结
本文介绍了LeetCode上关于链表的经典题目,包括链表反转、合并以及环形链表相关的题目。通过这些题目的练习,我们可以加深对链表数据结构的理解,并掌握相应的算法实现。在实际开发中,链表是一种非常有用的数据结构,熟练掌握链表操作对于提高编程能力具有重要意义。
Comments NOTHING