LeetCode[Linked List]: Partition List

来源:互联网 发布:正品代购软件 编辑:程序博客网 时间:2024/06/04 19:15

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
原创粉丝点击