给你一个单链表和一个数x,让小于x的结点都排到前面去(保证稳定性)。
大致思路:
刚开始我就像“反转链表”那道题一样想着头插法,先找到第一个>=x的结点然后再来遍历一次来头插,发现要考虑的因素特别多,还要考虑头结点会不会就是>=x的要被头插,那又像那道题一样要讨论。写出代码调好后,发现超时。。。
后来想想,这种方法确实是完全一点辅助空间都不用。干嘛不用辅助空间??况且,其实对于链表来说,如果只是新建“链表头结点”来重新设置指针,其实也没有用到辅助空间!有没有更简单的办法?
然后。。。我受到了冲击。。原来,只要来一个dummy1连接所有<x的结点,来一个dummy2连接所有>=x的结点,然后再拼接一下就行了。。(注意拼接到最后,结果链表的末尾->next=NULL)
AC代码:
/**
* 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)
return head;
if(head->next==NULL)
return head;
ListNode *dummy1 =new ListNode(0); //存前面的<x的结点
ListNode *dummy2 =new ListNode(0); //存后面的>=x的结点
ListNode *cur1 = dummy1;
ListNode *cur2 = dummy2;
//不需要先找到第一个>=x的结点!直接去把>=x的连起来,把<x的连起来
ListNode *p = head;
while(p)
{
if(p->val<x)
{
cur1->next = p;
cur1 = cur1->next;
}
else
{
cur2->next = p;
cur2 = cur2->next;
}
p = p->next;
}
//拼接
cur1->next = dummy2->next;
cur2->next = NULL;//末尾->next要指向空才行。如果原链表最后一个结点不是>=x的,则不会next==NULL
return dummy1->next; //注意,dummy是无意义的头结点,要返回->next
}
};