leetcode 链表排序

来源:互联网 发布:福州淘宝代运营 编辑:程序博客网 时间:2024/06/11 00:21

对链表排序,用归并排序。题目要求空间时间复杂度为O(nlogn),但是空间复杂度为O(1)

1.自己写的程序,时间复杂度为O(nlogn),但是空间复杂度为O(n)

用快慢指针(分别走2步和1步)找到中间节点。但是最后排序的部分,用复制将排好序的部分粘贴会原来链表中,这个方法比较笨,而且增加空间复杂度,并不满足题目要求

leetcode 提交的时候说runtime error,但自己执行是通过的,可能因为时间复杂度的原因吧,需要后期再改

void mergesort(ListNode* head, ListNode* as, ListNode* ae, ListNode* bs, ListNode* be){    vector<int> vec;    ListNode* ps = as;    ListNode* pe = be;    int i= 0;    int anum = ae - as;    int bnum = be - bs;    int ia = 0, ib = 0;    while(ia <= anum && ib <= bnum){        if(as->val <= bs->val){            vec.push_back(as->val);            as = as->next;            ia++;        }        else{            vec.push_back(bs->val);            bs = bs->next;            ib++;        }    }    while(ia <= anum){        vec.push_back(as->val);        as = as->next;        ia++;    }    while(ib <= bnum){        vec.push_back(bs->val);        bs = bs->next;        ib++;    }    int pnum = pe - ps;    int ip = 0;    while(ip <= pnum){        ps->val = vec[i++];        ps = ps->next;        ip++;    }}void merge(ListNode* head,ListNode* start, ListNode* end){    if(start < end){        ListNode* former=start, * latter = start;        int snum = end - start;        int latt = 0;        while(latt + 2 <= snum){            former = former->next;            latter = latter->next->next;            latt = latt + 2;        }        if(latt+1 == snum){            latter = latter->next;        }        merge(head,start,former);        merge(head,former->next,latter);        mergesort(head,start,former,former->next,end);    }    else        return;}


2.leetcode中大神的代码,这里粘贴是为了自己以后找起来方便

它是自底向上的,归并起来。step为1,2,4,8....

/** * merge the two sorted linked list l1 and l2, * then append the merged sorted linked list to the node head * return the tail of the merged sorted linked list */ListNode* merge(ListNode* l1, ListNode* l2, ListNode* head){    ListNode *cur = head;    while(l1 && l2){        if(l1->val > l2->val){            cur->next = l2;            cur = l2;            l2 = l2->next;        }        else{            cur->next = l1;            cur = l1;            l1 = l1->next;        }    }    cur->next = (l1 ? l1 : l2);    while(cur->next) cur = cur->next;    return cur;}/** * Divide the linked list into two lists, * while the first list contains first n ndoes * return the second list's head */ListNode* split(ListNode *head, int n){    //if(!head) return NULL;    for(int i = 1; head && i < n; i++) head = head->next;        if(!head) return NULL;    ListNode *second = head->next;    head->next = NULL;    return second;}ListNode *sortList(ListNode *head) {    if(!head || !(head->next)) return head;        //get the linked list's length    ListNode* cur = head;    int length = 0;    while(cur){        length++;        cur = cur->next;    }        ListNode dummy(0);    dummy.next = head;    ListNode *left, *right, *tail;    for(int step = 1; step < length; step <<= 1){        cur = dummy.next;        tail = &dummy;        while(cur){            left = cur;            right = split(left, step);            cur = split(right,step);            tail = merge(left, right, tail);        }    }    return dummy.next;}



其余补充的部分,对链接初始化和输出打印部分

/** * Definition for singly-linked list.*/  struct ListNode {      int val;      ListNode *next;      ListNode(int x) : val(x), next(NULL) {}  }; ListNode* init(int a[], int n){    ListNode* q = NULL, *head = NULL;    for(int i = 0; i < n; i++){        ListNode* p = new ListNode(0);        p->val = a[i];        if(i==0){//不要忽略头结点的赋值            head = q = p;            continue;        }        q->next=p;        q = q->next;    }    q->next = NULL;    return  head;    }void prints(ListNode* head){    while(head){        cout<<head->val<<" ";        head = head->next;    }}    int main(int argc, const char * argv[]) {    int a[]={2,5,3,7,9,4,1,8};    //int a[]={2,1};    ListNode* head =new ListNode(0);    head=init(a,8);    ListNode* L = sortList(head);    prints(L);    return 0;}


3.最后提交上去的版本,能运行通过且过程简单易懂,也是从别人那里看到的

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    void mergesort(ListNode* head, ListNode* as, ListNode* ae, ListNode* bs, ListNode* be){    vector<int> vec;    ListNode* ps = as;    ListNode* pe = be;    int i= 0;    int anum = ae - as;    int bnum = be - bs;    int ia = 0, ib = 0;    while(ia <= anum && ib <= bnum){        if(as->val <= bs->val){            vec.push_back(as->val);            as = as->next;            ia++;        }        else{            vec.push_back(bs->val);            bs = bs->next;            ib++;        }    }    while(ia <= anum){        vec.push_back(as->val);        as = as->next;        ia++;    }    while(ib <= bnum){        vec.push_back(bs->val);        bs = bs->next;        ib++;    }    int pnum = pe - ps;    int ip = 0;    while(ip <= pnum){        ps->val = vec[i++];        ps = ps->next;        ip++;    }}void merge(ListNode* head,ListNode* start, ListNode* end){    int hnum = end - start;    if(hnum > 0){        ListNode* former=start, * latter = start->next;        while(latter!= NULL && latter->next != NULL){            former = former->next;            if(latter->next->next == NULL)                latter = latter->next;                else                latter = latter->next->next;        }                merge(head,start,former);        merge(head,former->next,latter);        mergesort(head,start,former,former->next,end);    }    else        return;}    ListNode* sortList(ListNode* head) {        if(head == NULL || head->next == NULL)            return head;        ListNode* p = head;        while(p->next != NULL)            p = p->next;        merge(head,head,p);        return head;        }};


0 0