返回
Python 剖析 leetcode 86. Partition List:双指针巧妙分割链表
后端
2023-10-07 13:47:42
导读
在计算机科学中,链表是一种常用的数据结构,它由一系列节点组成,每个节点包含一个数据项和指向下一个节点的指针。链表操作是编程中常见且重要的任务,其中分割链表是一种常见且实用的操作。在 leetcode 86. Partition List 这道题中,我们需要将链表分割成两个子链表,其中一个子链表包含所有小于或等于给定值的节点,另一个子链表包含所有大于给定值的节点。
解题思路
这道题目的关键在于如何高效地将链表分割成两个子链表。一种常用的方法是使用双指针法。双指针法是一种利用两个指针同时遍历链表的技巧,它可以帮助我们快速地找到特定位置的节点或执行分割操作。
具体来说,我们可以使用两个指针 prev
和 curr
来遍历链表。prev
指针始终指向当前节点的前一个节点,curr
指针指向当前节点。我们从链表的头节点开始遍历,如果 curr
指针指向的节点值小于或等于给定值,则将该节点移动到分割后的第一个子链表中,并将 prev
和 curr
指针都向前移动一个节点。如果 curr
指针指向的节点值大于给定值,则将该节点移动到分割后的第二个子链表中,并只将 curr
指针向前移动一个节点,因为 prev
指针需要留在当前节点上。
通过这种方式,我们可以在遍历链表的同时将链表分割成两个子链表。分割完成后,我们可以将分割后的两个子链表连接起来,形成最终的分割结果。
Python 代码实现
def partition(head, x):
"""
Partition a linked list around a value x, such that all nodes less than x come before all nodes greater than or equal to x.
If x is contained within the list, the values of x only need to be after the elements less than x.
The partition element x can appear anywhere in the "right partition"; it does not need to appear between the left and right partitions.
:type head: ListNode
:type x: int
:rtype: ListNode
"""
# Initialize two pointers, prev and curr, to traverse the list.
prev = ListNode(0)
prev.next = head
curr = head
# Move the prev and curr pointers until we find the first node with a value greater than or equal to x.
while curr and curr.val < x:
prev = prev.next
curr = curr.next
# If we have reached the end of the list, return the original list.
if not curr:
return head
# Initialize two new lists, left_head and right_head, to store the partitioned lists.
left_head = ListNode(0)
right_head = ListNode(0)
# Append nodes to the left and right lists based on their values.
while curr:
if curr.val < x:
left_head.next = curr
left_head = left_head.next
else:
right_head.next = curr
right_head = right_head.next
curr = curr.next
# Connect the two lists and return the head of the partitioned list.
left_head.next = right_head.next
return prev.next
复杂度分析
- 时间复杂度:O(n),其中 n 是链表的长度。我们只需要遍历链表一次,因此时间复杂度为 O(n)。
- 空间复杂度:O(1),因为我们不需要额外的空间来存储数据。
结语
leetcode 86. Partition List 这道题目考察了双指针分割链表的基本操作。通过这道题,我们可以理解双指针法的原理和应用,并掌握链表分割的基本技巧。这种技巧在实际编程中非常有用,可以帮助我们解决各种各样的链表操作问题。