博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
148. Sort List (List)
阅读量:4573 次
发布时间:2019-06-08

本文共 4833 字,大约阅读时间需要 16 分钟。

Sort a linked list in O(n log n) time using constant space complexity.

 法I:快排。快排的难点在于切分序列。从头扫描,碰到>=target的元素,停止;从第二个字串扫描,碰到<=target的元素停止;交换这两个元素。这样的好处是:当数据元素都相同时,也能控制在logn次递归(否则需要O(n))。另外,要注意避免子序列只剩两个相等元素时的死循环。

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode* sortList(ListNode* head) {        if(head == NULL || head->next==NULL) return head; //only one element                ListNode* dummyHead1 = new ListNode(0);        ListNode* dummyHead2 = new ListNode(0);        ListNode* fastNode = dummyHead1;        ListNode* slowNode = dummyHead1;        ListNode* cur1, *cur2;        int tmp;        dummyHead1->next = head;                //fast, slow pointer to find the middle point        while(fastNode->next){            fastNode = fastNode->next;            if(fastNode->next) fastNode = fastNode->next;            else break;            slowNode = slowNode->next; //slowNode always point to the element before center(odd number)                                      // or the left center (even number)        }            //partition the sequence into two halves        dummyHead2->next = slowNode->next;        slowNode->next=NULL;        cur1 = dummyHead1;         cur2 = dummyHead2->next;        while(cur1->next&&cur2->next){           //stop when find an element in first half, value of whihch >= target           while(cur1->next && cur1->next->val < dummyHead2->next->val) cur1 = cur1->next;           //stop when find an element in second half,  value of which <= target           while(cur2->next && cur2->next->val > dummyHead2->next->val) cur2 = cur2->next;           if(!cur1->next || !cur2->next ) break;           tmp = cur1->next->val;           cur1->next->val = cur2->next->val;           cur2->next->val = tmp;           cur1 = cur1->next;           cur2 = cur2->next;                   }        while(cur1->next){            //stop when find an element in first half, value of which > target            //>= may lead to endless recursion if two equal elements left            while(cur1->next && cur1->next->val <= dummyHead2->next->val) cur1 = cur1->next;            if(!cur1->next) break;            cur2->next = cur1->next;            cur1->next = cur1->next->next;            cur2 = cur2->next;            cur2->next = NULL;        }        while(cur2->next){            //stop when find an element in second half, value of which < target            //<= may lead to endless recursion if two equal elements left            while(cur2->next && cur2->next->val >= dummyHead2->next->val) cur2 = cur2->next;            if(!cur2->next) break;            cur1->next = cur2->next;            cur2->next = cur2->next->next;            cur1 = cur1->next;            cur1->next = NULL;        }                //cascade two halves        head = sortList(dummyHead1->next);        cur2 = sortList(dummyHead2->next);        if(head==NULL) return cur2;        cur1 = head;        while(cur1->next){            cur1 = cur1->next;        }         cur1->next = cur2;        return head;    }};

 法II: 归并排序。由于是List,归并排序的好处是不用额外申请O(n)的空间

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode* sortList(ListNode* head) {        if(head == NULL || head->next==NULL) return head; //only one element                ListNode* dummyHead1 = new ListNode(0);        ListNode* dummyHead2 = new ListNode(0);        ListNode* fastNode = dummyHead1;        ListNode* slowNode = dummyHead1;        ListNode* cur1, *cur2, *cur;        dummyHead1->next = head;                //fast, slow pointer to find the middle point        while(fastNode->next){            fastNode = fastNode->next;            if(fastNode->next) fastNode = fastNode->next;            else break;            slowNode = slowNode->next; //slowNode always point to the element before center(odd number)                                      // or the left center (even number)        }        dummyHead2->next = slowNode->next;        slowNode->next = NULL;                //recursion        cur1 = sortList(dummyHead1->next);        cur2 = sortList(dummyHead2->next);                //merge        cur = dummyHead1;        while(cur1 && cur2){            if(cur1->val <= cur2->val){                cur->next = cur1;                cur1 = cur1->next;            }            else{                cur->next = cur2;                cur2 = cur2->next;            }            cur = cur->next;        }        if(cur1){            cur->next = cur1;        }        else{            cur->next = cur2;        }        return dummyHead1->next;    }};

 

转载于:https://www.cnblogs.com/qionglouyuyu/p/4853068.html

你可能感兴趣的文章
39.递推练习: 菲波那契数列(2)
查看>>
47..贪心 失恋28天-追女孩篇
查看>>
排序精讲
查看>>
【bzoj3172】 Tjoi2013—单词
查看>>
【uoj2】 NOI2014—起床困难综合症
查看>>
js return的用法
查看>>
for_each使用方法详解[转]
查看>>
Apache Storm 与 Spark:对实时处理数据,如何选择【翻译】
查看>>
c :set标签的陷阱(未解决)
查看>>
线性筛素数(欧拉筛)
查看>>
java 序列化与反序列化
查看>>
nginx安装环境
查看>>
Adventures with Testing BI/DW Application
查看>>
XML
查看>>
Flash Builder4注册机
查看>>
如何把网页变成灰色效果
查看>>
如何让程序(如java Hello)只启动一次?
查看>>
rpath 与runpath
查看>>
WPF星空效果
查看>>
SQL语言基础-基本概念
查看>>