MergeKSorted linked lists and return it as one sorted list. analyze and describe its complexity.
Method 1: brute-force cracking. Merge 1 and 2, merge 3, and merge 4... In this case, all linked list nodes are merged.
Complexity Analysis. Assume that there are K linked lists. The average length of each linked list is N.
Merge 1 and 2. The number of scan nodes is 2n.
12 and 3 are combined, and the number of scan nodes is 3n.
123 and 4 are merged, and the number of scan nodes is 4N.
......
123 .. K-1 and K merge, number of scan nodes is kN
Therefore, the number of scanning nodes is N (2 + 3 + 4 + 5 + 6 +... + k), the time complexity is O (nk2), and tietong times out.
Method 2: Use the divide and conquer method, which seems to cure all diseases. Suppose there are K linked lists and each linked list has n nodes, then K linked lists are divided into two parts, each part is a K/2 linked list. Merge K/2 linked lists first, and then merge K linked lists. The recursive formula is T (K) = 2 T (K/2) + T (NK), the time complexity of using the main theorem formula is O (nklogk)
You can use iteration methods, such as a linked list of, and. First merge, 14, and 25, store the results in, 2, and then merge 02, if there is 0 in the result, and then 01 in the merge, and the result is stored in 0, then lists [0] is required. The Code is as follows:
1/** 2 * definition for singly-linked list. 3 * struct listnode {4 * int val; 5 * listnode * Next; 6 * listnode (int x): Val (x), next (null) {} 7 *}; 8 */9 class solution {10 public: 11 listnode * mergeklists (vector <listnode *> & lists) {12 if (lists. empty () return NULL; 13 int n = lists. size (); 14 While (n> 1) {15 int K = (n + 1)/2; 16 for (INT I = 0; I <n/2; ++ I) 17 lists [I] = mergelists (lists [I], lists [I + K]); 18 N = K; 19} 20 return lists [0]; 21} 22 23 listnode * mergelists (listnode * LHS, listnode * RHs) {// merge two linked lists 24 if (! LHS) return RHS; 25 if (! RHS) return LHS; 26 listnode node (-1); 27 listnode * pre = & node; 28 while (LHS & RHs) {29 If (LHS-> Val <RHS-> Val) {30 pre-> next = LHS; 31 LHS = LHS-> next; 32} 33 else {34 pre-> next = RHS; 35 RHS = RHS-> next; 36} 37 pre = pre-> next; 38} 39 pre-> next = LHS? LHS: RHS; 40 return node. Next; 41} 42 };
Method 3: maintain a small root heap of K sizes. First, push the first node of each linked list into the heap, and then enter the following cycle: obtain the minimum element in the heap, place the next node of the element to the center until the heap is empty.
Assuming that K linked lists and N nodes in each linked list are still used, access to NK nodes is required. It takes the logk time to put a node into the heap each time. The time complexity is O (nklongk)
1/** 2 * definition for singly-linked list. 3 * struct listnode {4 * int val; 5 * listnode * Next; 6 * listnode (int x): Val (x), next (null) {} 7 *}; 8 */9 class solution {10 public: 11 struct CMP {12 bool operator () (const listnode * LHS, const listnode * RHs) const {13 return LHS-> Val> RHS-> val; 14} 15}; 16 17 public: 18 listnode * mergeklists (vector <listnode *> & lists) {19 if (lists. empty () Return NULL; 20 priority_queue <listnode *, vector <listnode *>, CMP> PQ; // construct the minimum heap 21 for (INT I = 0; I <lists. size (); ++ I) {// initialization, first put the first node of each linked list into the heap 22 if (lists [I]) {23 PQ. push (lists [I]); 24 lists [I] = lists [I]-> next; 25} 26} 27 listnode node (-1 ); 28 listnode * pre = & node; 29 While (! PQ. empty () {30 pre-> next = PQ. top (); 31 PQ. pop (); 32 pre = pre-> next; 33 If (pre-> next) PQ. push (pre-> next); // put the next node of the extracted node into the heap 34} 35 pre-> next = 0; 36 return node. next; 37} 38 };
Merge K sorted lists