数据结构与算法之 leetcode 链表经典题 反转 / 合并 / 环形链表 攻略

数据结构与算法阿木 发布于 5 天前 2 次阅读


链表经典题攻略:反转、合并与环形链表

链表是数据结构中的一种,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。链表在计算机科学中应用广泛,特别是在实现动态数据结构时。本文将围绕链表这一主题,探讨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上关于链表的经典题目,包括链表反转、合并以及环形链表相关的题目。通过这些题目的练习,我们可以加深对链表数据结构的理解,并掌握相应的算法实现。在实际开发中,链表是一种非常有用的数据结构,熟练掌握链表操作对于提高编程能力具有重要意义。