【链表】partition list

给你一个单链表和一个数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
    }
};

猜你喜欢

转载自blog.csdn.net/m0_38033475/article/details/92422259