题目描述
给定一个链表的头指针 pHead,以给定值 x 为基准,将链表分割成两部分。所有小于 x 的结点排在大于或等于 x 的结点之前。要求不能改变原来数据的顺序,且时间复杂度为 O(n),空间复杂度为 O(1)。
思路分析
处理这类链表分割问题,直接操作原链表容易破坏结构或丢失头节点信息。比较稳妥的做法是引入哨兵位(Sentinel Node)。
我们可以创建两个虚拟头结点 guardLess 和 guardGreater,分别作为'小于 x'和'大于等于 x'两个子链表的头部。遍历原链表时,根据当前节点的值将其尾插到对应的子链表中。这样既能保持相对顺序,又能避免处理空链表或头节点变化的边界情况。
具体步骤如下:
- 初始化:定义两个哨兵节点和两个尾指针
lessTail、greaterTail,初始指向各自的哨兵。 - 遍历:使用移动指针
curNode扫描原链表。若val < x,插入less链表并更新lessTail;否则插入greater链表并更新greaterTail。 - 拼接:遍历结束后,将
lessTail->next指向guardGreater->next,完成连接。 - 收尾:务必将新链表末尾的
next置为nullptr,防止出现环。最后释放哨兵节点内存,返回guardLess->next作为新头。
代码实现
class Partition {
public:
ListNode* partition(ListNode* pHead, int x) {
if (pHead == nullptr) return nullptr;
// 创建哨兵位头结点
ListNode* guardLess = new ListNode(-1);
ListNode* guardGreater = new ListNode(-1);
// 记录两个子链表的尾部,方便尾插
ListNode* lessTail = guardLess;
ListNode* greaterTail = guardGreater;
ListNode* curNode = pHead;
while (curNode) {
if (curNode->val < x) {
lessTail->next = curNode;
lessTail = lessTail->next;
} {
greaterTail->next = curNode;
greaterTail = greaterTail->next;
}
curNode = curNode->next;
}
lessTail->next = guardGreater->next;
greaterTail->next = ;
pHead = guardLess->next;
guardGreater;
guardLess;
pHead;
}
};


