LeetCode86. Partition List
原题地址
题目描述
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.
思路
题目的意思链表中小于x的元素在等于或者大于x的元素前面。
我原先的思路是c从头到尾遍历链表,设置一个pre和cur指针分别指向当前结点和当前结点的前一个结点,遇到比x的元素就把其插到head前面,并把这个元素删除(考虑到头结点,可以设置一个result结点,使result->next=head)。
while(cur){
if(cur->val<x){
pre->next=cur->next;
ListNode* tmp=new ListNode(0);
tmp->val=cur->val;
tmp->next=newhead->next;
newhead->next=tmp;
newhead=tmp;
cur=cur->next;
}
else{
pre=pre->next;
cur=cur->next;
}
后来提交的时候总有几个测试数据过不去,我才发现我这个思路存在问题,例如(1,2,3),x=3,这样就会返回(2,1,3),显然是错误的。其实我之前考虑的情况是x前面没有比x小的元素的情况,所以只要加上x前面的元素比x小的情况(此时pre,cur直接后移就行)。
while(cur&&cur->val<x){
if(cur->next==NULL)
break;//注意该语句的位置
pre=pre->next;
cur=cur->next;
newhead=newhead->next;
}
代码实现
/**
* 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) {
if(head==NULL || head->next==NULL)
return head;
ListNode* result=new ListNode(0);
result->next=head;
ListNode* newhead=result;
ListNode* pre=result;
ListNode* cur=head;
while(cur&&cur->val<x){
if(cur->next==NULL)
break;
pre=pre->next;
cur=cur->next;
newhead=newhead->next;
}
while(cur){
if(cur->val<x){
pre->next=cur->next;
ListNode* tmp=new ListNode(0);
tmp->val=cur->val;
tmp->next=newhead->next;
newhead->next=tmp;
newhead=tmp;
cur=cur->next;
}
else{
pre=pre->next;
cur=cur->next;
}
}
return result->next;
}
};
ps:我看到的另一种更简洁的思路,设置两链表分别存储比x小的元素和比x大(或者等于)的元素,最后将两个链表头尾相连即可。
ListNode p = new ListNode(0);
ListNode pHead = p;
ListNode q = new ListNode(0);
ListNode qHead = q;
//遍历
while(head != null){
if(head.val < x){//<x成一组
p.next = head;
p = p.next;
}else{//>=x成一组
q.next = head;
q = q.next;
}
head = head.next;
}
p.next = qHead.next;
q.next = null;//斩断后面的连接
return pHead.next;