LeetCode - 面试题 02.04. 分割链表

发布于:2025-06-01 ⋅ 阅读:(23) ⋅ 点赞:(0)

题目

面试题 02.04. 分割链表 - 力扣(LeetCode)

双指针合并思路

这个双指针的思路是将原链表分成两个子链表,然后再合并它们:

创建两个子链表:

  • 一个子链表用于存放所有小于x的节点(smalldummy开头)
  • 一个子链表用于存放所有大于等于x的节点(largedummy开头)

使用双指针维护两个子链表:

  • smallptr始终指向小值链表的尾部
  • largeptr始终指向大值链表的尾部
  • 这两个指针使我们能够在O(1)时间内向各自的链表添加新节点

遍历原链表:

  • 对于每个节点,根据其值与x的比较结果,将其添加到对应的子链表中
  • 重要的是,我们不是创建新节点,而是直接移动原链表中的节点

合并两个子链表:

  • 将大值链表的末尾节点的next指针设为nullptr(防止循环引用)
  • 将小值链表的末尾连接到大值链表的开头

这种方法的优势在于:

  • 时间复杂度为O(n),只需遍历链表一次
  • 空间复杂度为O(1),只使用了常数额外空间(两个dummy节点)

读者可能的错误写法

class Solution {
public:
    ListNode* partition(ListNode* head, int x) {
        if(head == nullptr)
        {
            return nullptr;
        }
        ListNode* smalldummy = new ListNode(0);
        ListNode* largedummy = new ListNode(0);

        ListNode* smallptr = smalldummy;
        ListNode* largeptr = largedummy;

        while(head)
        {
            if(head->val < x)
            {
                smallptr->next = head;
                smallptr = smallptr->next;
            }
            else
            {
                largeptr->next = head;
                largeptr = largeptr->next;
            }
            head = head->next;
        }
        smallptr->next = largedummy->next;

        return smalldummy->next;
    }
};

没有将大值链表的末尾节点的next指针设置为nullptr。

当你遍历完原链表后,大值链表的最后一个节点(largeptr)的next指针仍然指向原链表中的下一个节点,这可能会导致循环引用。

正确写法

class Solution {
public:
    ListNode* partition(ListNode* head, int x) {
        if(head == nullptr)
        {
            return nullptr;
        }
        ListNode* smalldummy = new ListNode(0);
        ListNode* largedummy = new ListNode(0);

        ListNode* smallptr = smalldummy;
        ListNode* largeptr = largedummy;

        while(head)
        {
            if(head->val < x)
            {
                smallptr->next = head;
                smallptr = smallptr->next;
            }
            else
            {
                largeptr->next = head;
                largeptr = largeptr->next;
            }
            head = head->next;
        }
        largeptr->next = nullptr;  // 这行很重要,防止循环引用
        smallptr->next = largedummy->next;

        return smalldummy->next;
    }
};

网站公告

今日签到

点亮在社区的每一天
去签到