LeetCode86. 分隔链表

要根据链表节点的值是否大于等于x将链表划分为两段,首先需要链表中大于等于x和小于x的节点的个数,所以无法直接在原链表上做修改。

既然要分开大于等于x的值和小于x的值,我们可以考虑开两个链表,这样按顺序扫描原链表的时候,小于x的值接到第一个链表,大于等于x的值接到第二个链表。

然后再把这两个链表连接起来,就得到了满足题目条件的链表,且节点之间的相对顺序没变。

由于链表里可能一个大于等于x或者小于x的值都不存在,所以开的两个链表是有可能为空的,因此我们需要引入虚拟头节点。

不妨设两个链表的虚拟头节点为leftDummy和rightDummy,然后要遍历原链表,将节点连接到两个新链表,因此两个新链表需要尾指针,分别设为leftTail和rightTail。

这样,遍历一下原链表,如果当前节点的值小于x,则连接到leftTail,然后leftTail向后移动;
如果当前节点的值大于等于x,则连接到rightTail,然后rightTail也向后移动。

遍历完原链表之后,两个新链表就连接起来了小于x和大于等于x的节点了,这时需要连接起来两个链表。
只需要让leftTail -> next = rightDummy -> next;也就第一个链表的尾指针指向第二个链表虚拟头节点的下一个节点(即第一个节点)。
然后还需要rightTail -> next = NULL; 链表最后一个节点的next指针需要指向空。

返回值就是leftTail -> next(虚拟头节点的下一个节点)。

class Solution {
public:
    ListNode* partition(ListNode* head, int x) {
        auto leftDummy = new ListNode(-1), rightDummy = new ListNode(-1);      //两个链表的虚拟头节点
        auto leftTail = leftDummy, rightTail = rightDummy;
        for(auto p = head; p != NULL; p = p -> next) {
            if(p -> val < x) {
                leftTail -> next = p;
                leftTail = leftTail -> next;
            } else {
                rightTail -> next = p;
                rightTail = rightTail -> next;
            }
        }
        leftTail -> next = rightDummy -> next;            //连接左右两个链表
        rightTail -> next = NULL;                         //最后一个节点的next指针指向空
        return leftDummy -> next;
    }
};
原文地址:https://www.cnblogs.com/linrj/p/13332946.html