LeetCode[Linked List]: 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.

最愚蠢的做法

思路:首先找到较小部分的尾,然后挨个往后找,找到属于较小部分的就移动到较小部分的尾,并更新较小部分的尾。

ListNode *partition(ListNode *head, int x) {
    ListNode *dummyHead = new ListNode(0);
    dummyHead->next = head;
    ListNode *part1Tail = dummyHead, *part2Tail = dummyHead;

    while (part1Tail->next && part1Tail->next->val < x) {
        part1Tail = part1Tail->next;
        part2Tail = part2Tail->next;
    }

    while (part1Tail->next && part2Tail->next) {
        if (part2Tail->next->val >= x)
            part2Tail = part2Tail->next;
        else {
            ListNode *moveNode = part2Tail->next;
            part2Tail->next = part2Tail->next->next;
            moveNode->next  = part1Tail->next;
            part1Tail->next = moveNode;
            part1Tail = moveNode;
        }
    }

    return dummyHead->next;
}

Run Time: 68ms

更清晰的解法

思路:生成两条链表,小于x的插入到part1的尾部,其余的插入到part2的尾部;最后将两条链表连接起来即可。

ListNode *partition(ListNode *head, int x) {
    ListNode *part1DummyHead = new ListNode(0), *part2DummyHead = new ListNode(0);
    ListNode *part1Tail = part1DummyHead,        *part2Tail = part2DummyHead;

    for (ListNode *cur = head; cur != NULL; cur = cur->next) {
        if (cur->val < x) {
            part1Tail->next = cur;
            part1Tail = cur; // No need to set cur->next as NULL
        }
        else {
            part2Tail->next = cur;
            part2Tail = cur; // No need to set cur->next as NULL
        }
    }

    part1Tail->next = part2DummyHead->next;
    part2Tail->next = NULL;

    return part1DummyHead->next;
}


Run Time: 72ms

更精简的代码

可用指向指针的指针消除两行重复代码。

ListNode *partition(ListNode *head, int x) {
    ListNode *part1DummyHead = new ListNode(0), *part2DummyHead = new ListNode(0);
    ListNode *part1Tail = part1DummyHead,        *part2Tail = part2DummyHead;

    for (ListNode *cur = head; cur != NULL; cur = cur->next) {
        ListNode **optTail = cur->val < x ? &part1Tail : &part2Tail;
        (*optTail)->next = cur;
        (*optTail) = cur;  // No need to set cur->next as NULL
    }

    part1Tail->next = part2DummyHead->next;
    part2Tail->next = NULL;

    return part1DummyHead->next;
}


Run Time: 44ms

更好地,可用指针数组消除循环内的判断。

ListNode *partition(ListNode *head, int x) {
    ListNode *part1DummyHead = new ListNode(0), *part2DummyHead = new ListNode(0);
    ListNode *partTails[2] = {part1DummyHead, part2DummyHead};

    for (ListNode *cur = head; cur != NULL; cur = cur->next) {
        partTails[cur->val >= x]->next = cur;
        partTails[cur->val >= x] = cur;  // No need to set cur->next as NULL
    }

    partTails[0]->next = part2DummyHead->next;
    partTails[1]->next = NULL;

    return part1DummyHead->next;
}


Run Time: 20ms

可参见:C语言优化实例:循环中减少判断

注:以上各解法,时间复杂度均为O(N),空间复杂度均为O(1)。以上各解法均未考虑内存泄露的问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值