problem:
Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.
You should preserve the original relative order of the nodes in each of the two partitions.
For example,
Given 1->4->3->2->5->2
and x = 3,
return 1->2->2->4->3->5
.
Hide Tags
题意:类似于快速排序的第一步,将乱序的链表分成两部分,小于target的放在前面,不小于target的放后面
thinking:
(1)利用快速排序的思想,将小于目标值的结点前移。但是,由于快速排序是不稳定的,所以不满足题目稳定性的要求,若套用快速排序必然是错的
(2)那就改造快速排序。快速排序的双指针游走方向是相反的,这就导致了排序的不稳定性。如果双指针同时沿着递增的方向游走,则是稳定的。
(3)对于本题,除了游走的双指针,还要增加前驱指针和最后一个小于目标值的后驱指针
code:
改造快速排序:
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *partition(ListNode *head, int x) { ListNode *p=NULL; //左指针 ListNode *after=NULL; //指向第一个不小于x的结点 ListNode *pre=head; //q的前驱结点 ListNode *q=head; //右指针 while(q!=NULL) { ListNode *tmp=q->next; if(q->val<x) { if(after==NULL) //从第一个结点小于x { if(p==NULL) { p=q; head=p; } else p=p->next; //不用移动 } else //第一个结点大于X { if(p==NULL) { p=q; head=p; p->next=after; if(after->next==q) //p q之间只有一个结点不小于X pre=after; pre->next=tmp; } else { p->next=q; p=p->next; p->next=after; if(after->next==q) //p q之间只有一个结点不小于X pre=after; pre->next=tmp; } } } else { if(after==NULL) after=q; pre=q; //连续结点不小于X } q=tmp; } return head; } };
时间: 2024-10-05 06:16:09