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,
Given1->4->3->2->5->2and x = 3,
return1->2->2->4->3->5.
题意:给定一个链表和一个值x,将它划分为所有小于x的节点出现在大于或等于x的节点之前。值得注意的是,不要改变相对顺序,对1->4->3->2->5->2而言,给定x=4则返回1->3->2->2->4->5,前半段不应是按递增的顺序,但相对位置不变即可。
思路:找到第一个值不小x的结点和其前驱pre,然后从该结点往后遍历,找到值小于x结点,然后将其依次放在前驱之后,对于前驱pre则不断的向其后继移动。
方法一:初始代码:思想是,找到第一个大于或者等于x的值及其前驱,然后从x开始向后遍历,但是在遍历的过程,需要用到x前驱的信息,所以又重新定义了一个新的变量preCur。
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 class Solution { 10 public: 11 ListNode *partition(ListNode *head, int x) 12 { 13 if(head==NULL||head->next==NULL) 14 return head; 15 ListNode *nList=new ListNode(0); 16 nList->next=head; 17 ListNode *pre=nList; 18 ListNode *cur=head; 19 20 while(cur) //找到节点及其前驱pre 21 { 22 if(cur->val >=x) 23 break; 24 pre=cur; 25 cur=cur->next; 26 27 } 28 ListNode *preCur=cur; //cur是不停的向后遍历,preCur则是其前行过程中的前驱 2930 31 while(cur) 32 { 33 if(cur->val <x) 34 { 35 ListNode *temp=cur->next; 36 cur->next=pre->next; 37 pre->next=cur; 38 preCur->next=temp; 39 pre=pre->next; 40 cur=temp; 41 } 42 else 43 { 44 preCur=cur; 45 cur=cur->next; 46 } 47 } 48 return nList->next; 49 } 50 };
方法一:改进版。很明显,cur为第一个值不小于x的节点,然后通过其后继的值来作为判断前行或是将小于x的节点放在前面,这样就可以省去变量。
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 class Solution { 10 public: 11 ListNode *partition(ListNode *head, int x) 12 { 13 ListNode *nList=new ListNode(0); 14 nList->next=head; 15 ListNode *pre=nList; 16 ListNode *cur=head; 17 18 while(pre->next&&pre-next->val < x) 19 pre=pre->next; 20 21 cur=pre; 22 while(cur->next) 23 { 24 if(cur->next->val <x) 25 { 26 ListNode *temp=cur->next; 27 cur->next=temp->next; 28 temp->next=pre->next; 29 pre->next=temp; 30 pre=pre->next; 31 } 32 else 33 { 34 cur=cur->next; 35 } 36 } 37 return nList->next; 38 } 39 };
方法三:可以通过将值小于x的结点全部拿出来组成一个新的链表,然后将这个新的链表插入第一个值不小于x之前即可。来源Grandyang的博客
1 class Solution 2 { 3 public: 4 ListNode *partition(ListNode *head,int x) 5 { 6 if(head==NULL) return head; 7 ListNode *small=new ListNode(-1); 8 ListNode *big=new ListNode(-1); 9 10 big->next=head; 11 ListNode *cur=small,*p=small; 12 while(cur->next) 13 { 14 if(cur->next->val <x) 15 { 16 p->next=cur->next; 17 p=p->next; 18 //小于x的值,不停的移到small中,然后cur重新连接 19 cur->next=cur->next->next; 20 p->next=NULL; //注意要记得给p->next=NULL 21 } 22 else 23 cur=cur->next; 24 } 25 p->next=big->next; //拼接 26 return small->next; 27 } 28 }