思路:思路是受了快排中将数组通过一个主元分成两部分的思路启发。因此,保存两个指针p1和p2,p1指向当前最后一个值小于x的结点,p2指向当前正在检查的结点,处于head指针和p1(包括p1指针指向的结点)之内的所有结点都满足值小于x,处于p1的后继结点(p1->next指向的结点)和p2的前驱结点(该结点的next指向p2)之间的所有结点的值大于等于x,如果p2的值大于等于x,则让p2指向其下一个结点,否则,将p2指向的结点放置到p1指向的结点之后。在这个过程中需要保留另外两个指针,一个指针p2指向p1的后继结点,p4指向p2的前驱结点。
初始时,p1=NULL,p4=NULL,p2=head, p3=head;
AC代码:
class Solution {
public:
ListNode* partition(ListNode* head, int x) {
if(head==NULL || head->next==NULL)
return head;
ListNode *p1, *p2, *p3, *p4;
// p1为最后一个指小于等于X的结点,p2为当前正在检测的结点
// p3为p1的后继,p4为p2的前驱
p1=p4=NULL;
p2=p3=head;
while(p2!=NULL){
if(p2->val < x){
// p1=NULL说明之前的结点值都大于X,当前找到的结点是第一个值小于等于x的结点,且当前结点为新的头结点
if(p1==NULL){
// 当p4为NULL时表示p2为head结点
if(p4!=NULL){
p4->next = p2->next;
p2->next = p3;
// 调整完后
head = p2;
p1 = p2;
p2 = p4->next;
}else{
p1 = head;
p3 = p1->next;
p4 = p2;
p2 = p2->next;
}
}else{
// 若p2是p1的后继,即多个连续的小于x的值
if(p2==p3){
p4 = p2;
p1 = p2;
p2 = p2->next;
p3 = p2;
}else{
p1->next = p2;
p4->next = p2->next;
p2->next = p3;
// 调整完后
p1 = p2;
p2 = p4->next;
}
}
}else{
p4 = p2;
p2 = p2->next;
}
}
return head;
}
};