The NLGN time order of the linked list is realized, and the constant space.
Think, meet the complexity of the time is also fast platoon, heap, merge. Think of the worst of the fast row is also N-side, give up, heap words seemingly at least to make up a heap to the left and right two pointers to build is more convenient. Then I think it's going to be a merger.
Or saw the justdoit of the great God. I also knocked a bit.
Use the fast and slow pointer to find the middle, divide into two lists, then recursively, then merge. As follows:
/** Definition for singly-linked list. * struct ListNode {* int val; * ListNode *next; * ListNode (int x) : Val (x), Next (NULL) {}}; */classSolution { Public: ListNode*sortlist (ListNode *head) { if(!head | |!head-NEXT)returnHead; ListNode*fast = head, *slow =Head; while(Fast-Next && fast-nextnext) {Fast= Fast, NextNext; Slow= SlowNext; } Fast=slow; Slow= SlowNext; FastNext =NULL; Fast=Sortlist (head); Slow=sortlist (slow); returnmergelist (fast, slow); } ListNode*mergelist (ListNode *l1, ListNode *L2) { if(!L1)returnL2; if(!L2)returnL1; ListNode*pre =NewListNode (0); ListNode*mer =Pre; while(L1 &&L2) { if(L1, Val < L2,val) {MerNext =L1; L1= L1Next; Mer= MER-Next; } Else{merNext =L2; L2= L2Next; Mer= MER-Next; } } if(L1) MerNext =L1; if(L2) MerNext =L2; Mer= Pre-Next; Delete pre; returnmer; }};View Code
But the above does not conform to the constant space. The constant space is directly attached:
//non-recursive, spatial complexity is constant/** Definition for singly-linked list. * struct ListNode {* int val; * ListNode *next; * ListNode (int x) : Val (x), Next (NULL) {}}; */classSolution { Public: ListNode*sortlist (ListNode *head) { if(Head = =NULL)returnHead; ListNode*leftlist, *rightlist, *tail, *temp; //the number of times each merge, when the number of merges is 1, it means that there is no merge, indicating that the merge is complete intMergecount; intWidthsize =1;//each time the width of the linked list is merged, the initial value is 1, (2,4,8,....) intLeftsize;//left linked list size intrightsize; while(true)//exit condition is Mergecount = 0 { //tail points to the last node of the currently merged list, which is emptied before each merge starts//before each merge starts Leftlist points to the latest head, merging times 0Mergecount =0; Tail=NULL; Leftlist=Head; Rightlist=NULL; //Leftlist will point to the left-linked list of the next segment after each two linked list is merged//If there is no next left-linked list, the merge is complete, so the leftlist//as a condition of judgment while(leftlist) {++mergecount;//The number of trips per merge, to 1 o'clock means no merge//find the location of the rightlist, by the way, calculate the leftsize sizeRightlist = leftlist;//swipe backward from left linked listLeftsize =0; Rightsize=0; for(inti =0; i < widthsize; ++i) {if(rightlist) {++leftsize; Rightlist= rightlist->Next; } Else //The last left linked list is not enough for an interval length, but the list has been traversed to complete the lookup Break; } //find the header nodes of two linked lists that need to be merged, and the sizeRightsize = widthsize;//calculate by Max to determine if you want to add a pointer after traversing//interval length as a merging cycle condition, merging an interval-1, until two intervals are complete while(Leftsize >0|| ((Rightsize >0) &&rightlist)) { //temp Saves the temporarily smaller node, tail always saves the end of the chain//the first thing to consider is whether an interval has been exhausted, because if the interval is complete, leftlist//or rightlist, because moving back one unit will point to another interval . if(Leftsize = =0) { //i.e. ((rightsize > 0) && rightlist) is truetemp =rightlist; Rightlist= rightlist->Next; --rightsize; } Else if(Rightsize = =0|| Rightlist = =NULL) { //Leftsize is not 0, notice that the right-hand list merges the rightlist pointer//move to the back, which is the leftmost element of the next merge pairtemp =leftlist; Leftlist= leftlist->Next; --leftsize; }//the rest of the situation is that two merges are not empty for the remaining elements to be merged. Else if(Leftlist->val <= rightlist->val) {Temp=leftlist; Leftlist= leftlist->Next; --leftsize; } Else if(Leftlist->val > rightlist->val) {Temp=rightlist; Rightlist= rightlist->Next; --rightsize; } //find a smaller element, change the list to point to smaller elements if(Tail = =NULL) { //first found element, fixed head nodeHead =temp; Tail=temp; } Else{Tail->next =temp; Tail= tail->next;//tail always points to the last well-ordered node } }//While (leftsize > 0 | | ((rightsize > 0) && rightlist)) //a merge pair is completed, which has been mentioned before rightlist points to the leftmost node of the next merge pairLeftlist =rightlist; Tail->next =leftlist; }//While (leftlist)Tail->next = NULL;//tail points to the last node, merges and then sets tail next to empty.//Merge Complete judgment if(Mergecount <=1) returnHead; Widthsize*=2; } returnNULL; }View Code
can also be seen on his homepage.
Leetcode Sort List