LeetCode | 148. sorted list

The original title ( Medium ):

  In  O ( n-  log  n- complexity and the space complexity of constant grade, sort of the list) time.

  

 

 

 

Ideas: from the bottom up (bottom-to-up), merge sort (Merge Sort)

  Subject to time complexity and space complexity of the requirements made, much of the sort commonly used method for the number of levels, since there is not a doubly linked list, so fast row is unlikely to be used merge , but merge is a general need for a an auxiliary array, the spatial complexity is O (n), according to the general nature can not merge ideas. We can consider the merger bottom-up, rather than top-down recursive merge, is to start directly from twenty-two merger, then forty-four merger ....... until the end.

 

  So how to separate list twenty-two again twenty-two merge it? First, use a round integer variable size records required number of nodes twenty-two separate and merge, is a twice each time doubling the value of (1,2,4 ....), we can use bit computing to achieve twice the multiplier . Then how to separate it? How to separate the list every two nodes into a left and right, as stpe1 the same? We need to use this size to cut list (step1 of size 1), starting from the head of the list, through size nodes (including the head node), put the chain off , disconnect the left is the left half of the right of is the right half of size, such as 4> 3 -> ..., becomes disconnected after 4,3 -> ...., case 4 is a left half, the right half portion 3 is, how the right half of the confirmed down in the list? The list continues to cut, from (3 starting point of the right half of departure), through size nodes (including node departure) after disconnecting the list, left and right case portions are available, and can be merged, as for two merge the two ideas not repeat them here, because the problem is how to separate two two two two not merge. Press said that we need a cutting function: starting from a specified starting point beg, came after n nodes, to beg + n that node to the next node returns, before that, first beg + n nodes that bring up the rear (first record next temporary variable, then the next blank).

  We can summarize our first twenty-two merge what has been done

  1. Cutting a list, get the starting point of the left and right halves
  2. A re-cut chain, to give a starting point of the left half of the right half twenty-two merge and lower
  3. Merge left and right parts

  Then we can continue the second merger in accordance with the left half of the lower starting point for the first time obtained a merge merged. Until it reaches the end of the list.

  But for the first time merge not doing enough, we have assumed that the left and right portions merge Well, the results obtained so naturally it is 3-> 4, it is clear that the problem is not reconnected back on the list, we are on the cutting function once you have the starting point for the next merge, but we should not be connected directly to the starting point, because the next time merge has not yet begun, at least we need to wait for the next merge after the completion of the connection, so we need a pointer variable record of that merger the last node, that is, in the example of 4 in this node, we need to merge it with the head of the next node after the completion of the connection. So we need to be responsible for merging the function returns the first node after the merger.

. 1 ListNode the sortList * (* ListNode head) {
 2  
. 3      ListNode dummyHead ( 0 );
 . 4      dummyHead.next = head;
 . 5      ListNode * TEMP = head;
 . 6      int length = 0 ;
 . 7      // calculate the length of the list 
. 8      the while (TEMP)
 . 9      {
 10          length ++ ;
 . 11          TEMP = temp-> next;
 12 is      }
 13 is  
14      // without exceeding the length of the chain, the size of each array is increased twice a merge 
15      for ( int= size . 1 ; size <length; size = << . 1 )
 16      {
 . 17          // responsible for recording the end of the merged nodes, the connection time for the next merge 
18 is          ListNode * = tail & dummyHead;
 . 19          ListNode * CUR = dummyHead.next;
 20 is          the while (CUR) {
 21 is              Auto left = CUR;        
 22 is              Auto right = cut (left, size);     // first cut, starting from the left half, the starting point to obtain the left and right portions 
23 is              CUR cut = (right, size);         // second cut, starting from the right half, the starting point is obtained (using recording cur) of the right half and the left half of the next merged 
24              tail-> next = Merge (left , right);    // merge the left and right portions, and spend the time merge tail node connected to the first node after this time merging 
25              the while (tail-> Next) = tail tail-> Next;     // get merged after this time the tail node 
26          }
 27      }
 28      return dummyHead.next;
 29 }

  Cutting function: from a given starting point beg departure, came after n nodes, to beg + n that node to the next node returns, before that, the first beg + node n rear (first record next temporary variable , then the next blank).

. 1 ListNode * Cut (ListNode the begin *, int size) {
 2      the while (--size && the begin) the begin = begin-> Next; // across nodes including their size, it is --size 
. 3  
. 4      IF ! (The begin ) return NULL;     // if the cycle ends begin to empty, explained that it had come to the end of the list, the starting point of the next section does not exist, do not bring up the rear, and has no back up. 
. 5      ListNode * = begin- Next> Next;     // record the start of the next part for returning 
. 6      begin-> Next = NULL;             // rear 
. 7      return Next;
 . 8 }

  The combined function: the left and right portions were combined in the order, returns the first node and merged.

 1 ListNode* merge(ListNode* l, ListNode* r) {
 2     ListNode dummyHead(0);
 3     ListNode* temp = &dummyHead;
 4     while (l&&r)
 5     {
 6         if (l->val>r->val)
 7         {
 8             temp->next = r;
 9             temp = r;
10             r = r->next;
11         }
12         else
13         {
14             temp->next = l;
15             temp = l;
16             l = l->next;
17         }
18     }
19     temp->next = l ? l : r;
20     return dummyHead.next;
21 }

Guess you like

Origin www.cnblogs.com/MisakiJH/p/11742470.html