Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
Idea: The most likely thing to think about this is that (assuming there is a K list) linked list 1, 2 merge, then its results 12 and 3 merged, and so on, and finally the 123--k-1 and K merge. As for the merging of the two linked lists, see the analysis of merge sorted lists. analysis of complexity see Justdoit's blog . Algorithm complexity: Assuming that the average length of each list is n, then 1, 2 merge, Traverse 2n nodes, 12 results and 3 merge, traverse 3n nodes; The result of the 123...k-1 is combined with k, traversing the KN nodes, traversing n (2+3+4+....K) =n* (k^2+k-2)/2 in total, so the time complexity is O (n (k^2+k-2)/2) =o (nk^2). Second, we can think of the idea of divided treatment, 22 merger until the end.
For method One,
1 classSolution {2 Public:3 //storing linked lists with vectors4ListNode *mergeklists (Vector<listnode *> &lists)5 {6 if(lists.size () = =0)returnNULL;7ListNode *res=lists[0];//Remove the first linked list8 for(intI=1; I<lists.size (); i++)//repeated calls9res=mergetwolist (Res,lists[i]);Ten One returnRes; A } - - //Merge Sort theListNode *mergetwolist (ListNode *head1,listnode *head2) - { -ListNode node (0);//to create a predecessor node for a head node -ListNode *res=&node; + while(head1&&head2) - { + if(head1->val<=head2->val) A { atres->next=Head1; -Head1=head1->Next; - } - Else - { -res->next=head2; inHead2=head2->Next; - } toRes=res->Next; + } - the if(HEAD1) *res->next=Head1; $ Else if(head2)Panax Notoginsengres->next=head2; - the returnNode.next; + } A};
For method Two: It is difficult to think of, 22 when merging, the selection of linked list.
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 classSolution {Ten Public: OneListNode *mergeklists (Vector<listnode *> &lists) A { - intlen=lists.size (); - if(len==0) the returnNULL; - - while(len>1) - { + intk= (len+1) >>1; - + for(intI=0; i<len/2;++i) A { atLists[i]=mergetwolists (lists[i],lists[i+K]); - } -len=K; - } - returnlists[0]; - } in -ListNode *mergetwolists (ListNode *head1,listnode *head2) to { +ListNode *nlist=NewListNode (-1); -nlist->next=Head1; theListNode *pre=nList; * $ while(head1&&head2)Panax Notoginseng { - if(Head1->val >head2->val) the { +pre->next=head2; AHead2=head2->Next; the } + Else - { $pre->next=Head1; $Head1=head1->Next; - } -Pre=pre->Next; the } - Wuyi if(HEAD1) the { -pre->next=Head1; Wu } - Else Aboutpre->next=head2; $ - returnNlist->Next; - } -};
Another approach is to maintain a minimal heap of methods, maintaining a minimum heap of size k, initializing the elements in the heap as the table header for each linked list, and automatically sequencing them, then extracting the smallest elements into the new linked list, then pressing the smallest element into the heap, and then selecting the smallest element from the heap the next time. The complexity of the elements added to the heap is O (Longk), with a total of KN elements added to the heap, so the complexity is as O (NKLOGK) as the algorithm 2. The specific code is as follows:
1 classSolution2 {3 Private:4 structCMP5 {6 BOOL operator()(ConstListNode *a,ConstListNode *b)7 {8 returnA->val >b->Val;9 }Ten } One Public: A //storing linked lists with vectors -ListNode *mergeklists (Vector<listnode *> &lists) - { the intn=lists.size (); - if(n==0)returnNULL; - -ListNode node (0); +ListNode *res=&node; - +Priority_queue<listnode*,vector<listnode*>,cmp>que; A at for(intI=0; i<n;i++) - { - if(Lists[i]) - Que.push (List[i]); - } - in while(!que.empty ()) - { toListNode *p=que.top (); + Que.pop (); -res->next=p; theres=p; * $ if(p->next)Panax NotoginsengQue.push (p->next); - } the + returnNode.next; A } the}
In this article, a lot of the analysis process is from Justdoit and Grandyang blog.
[Leetcode] Merge K sorted lists merge K sorted list