返回

划分为二:精解 LeetCode 第 86 号问题「分割链表」

见解分享

引言

链表是一种重要的数据结构,在计算机科学和软件开发中广泛使用。LeetCode 第 86 号问题「分割链表」考查了我们对链表操作的理解和解决问题的能力。

问题陈述

给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。链表中每个节点包含一个整数,且保证链表中至少有一个节点。

示例

输入:

head = [1,4,3,2,5,2]
x = 3

输出:

[1,2,2,4,3,5]

解题思路

为了解决这个问题,我们可以采用双指针法:

  1. 创建两个虚拟头结点: 分别指向小于 x 和大于或等于 x 的节点。
  2. 初始化两个指针: 一个指针指向原链表的第一个节点,另一个指针指向小于 x 节点的虚拟头结点。
  3. 遍历原链表:
    • 若当前节点值小于 x,则将其插入到小于 x 节点的虚拟头结点后。
    • 否则,将其插入到大于或等于 x 节点的虚拟头结点后。
  4. 合并两个链表: 将小于 x 节点的虚拟头结点的下一个节点指向大于或等于 x 节点的虚拟头结点的下一个节点。
  5. 返回小于 x 节点的虚拟头结点的下一个节点,即分割后的链表头结点。

代码实现

def partition(head, x):
    # 创建虚拟头结点
    less_dummy = ListNode(0)
    greater_dummy = ListNode(0)
    
    # 初始化指针
    less = less_dummy
    greater = greater_dummy
    curr = head
    
    # 遍历原链表
    while curr:
        if curr.val < x:
            # 将小于 x 的节点插入到小于 x 节点的链表中
            less.next = curr
            less = less.next
        else:
            # 将大于或等于 x 的节点插入到大于或等于 x 节点的链表中
            greater.next = curr
            greater = greater.next
        # 指向下一个节点
        curr = curr.next
    
    # 合并两个链表
    less.next = greater_dummy.next
    
    # 返回小于 x 节点的链表头结点
    return less_dummy.next

复杂度分析

  • 时间复杂度:O(n),其中 n 为链表的长度。
  • 空间复杂度:O(1),因为我们只使用了常数个额外空间。

总结

通过采用双指针法,我们可以高效地解决 LeetCode 第 86 号问题「分割链表」。理解链表操作的基本原理和算法技巧对于解决此类问题至关重要。希望本文能够帮助你加深对链表操作的理解,提升你的算法解决能力。