分割链表
给你一个链表的头节点 head
和一个特定值 x
,请你对链表进行分隔,使得所有 小于 x
的节点都出现在 大于或等于 x
的节点之前。
你不需要 保留 每个分区中各节点的初始相对位置。
示例 1:
输入:head = [1,4,3,2,5,2], x = 3
输出:[1,2,2,4,3,5]示例 2:
输入:head = [2,1], x = 2
输出:[1,2]
解题思路:
使用双指针的思路来解决链表分区问题,通过创建两个新链表分别存储小于 x
和大于等于 x
的节点,最后合并这两个链表得到结果。
- 虚拟头节点初始化:分别为值小于
x
和大于等于x
的节点创建虚拟头节点head1
和head2
,并将它们的next
指针初始化为NULL
。 - 遍历原链表:遍历原链表,根据节点值与
x
的大小关系,将节点连接到对应的链表尾部。 - 断开节点连接:在将节点连接到新链表后,断开该节点与原链表的连接,避免形成环。
- 合并链表:将存储大于等于
x
节点的链表连接到存储小于x
节点的链表尾部。 - 释放虚拟头节点:释放创建的两个虚拟头节点。
- 返回结果:返回合并后链表的头节点。
struct ListNode* partition(struct ListNode* head, int x) {// 小的放 list1,大的放 list2struct ListNode* head1,* tail1,* head2,* tail2;head1 = tail1 = (struct ListNode*)malloc(sizeof(struct ListNode));head2 = tail2 = (struct ListNode*)malloc(sizeof(struct ListNode));// 初始化虚拟头节点的 next 指针head1->next = NULL;head2->next = NULL;struct ListNode* cur = head;while (cur) {struct ListNode* next = cur->next; // 保存当前节点的下一个节点if (cur->val < x) {tail1->next = cur;tail1 = tail1->next;tail1->next = NULL; // 断开当前节点与原链表的连接} else {tail2->next = cur;tail2 = tail2->next;tail2->next = NULL; // 断开当前节点与原链表的连接}cur = next;}tail1->next = head2->next;// 合并两个链表struct ListNode* result = head1->next;// 保存结果链表头节点free(head1);// 释放虚拟头节点free(head2);return result;
}