# Merge k sorted lists - LeetCode (2023)

## Problem definition

·

Published in

Geek for technology

·

·

4 days ago

You get a series`k`linked lists`arena`, each linked list is sorted in ascending order.

Merge all linked lists into a sorted linked list and return it.

Example 1:

`Input: lister = [[1, 4, 5], [1, 3, 4], [2, 6]]Output: [1, 1, 2, 3, 4, 4, 5, 6]Explanation: The linked lists are:[1->4->5,1->3->4,2->6]combine them into a sorted list:1->1->2->3->4->4->5->6`

Example 2:

`Input: lister = []Exit: []`

Example 3:

`Input: lister = [[]]Exit: []`

Limitations:

`- k == list.length- 0 <= k <= 10^4- 0 <= list[i].length <= 500- -10^4 <= blade[i][j] <= 10^4- lists[i] are sorted in ascending order.- The sum of list[i].length will not exceed 10^4.`

## Method 1: Brute force

In one of our previous blog posts, we discussed how to do thisSort a linked list one by one. In this problem we need to merge a sorted K linked list.

A simple solution would be to combine all k linked lists into one list (in any order). Then use the merge sort algorithm described inSort the listPosition. The worst time complexity of this approach isO(n * log(n)), Where`N`is the total number of nodes in all k lists. This approach is inefficient because we no longer use sorted lists.

Let's see the C++ snippet of this approach below:

`ListNode* getLastNode(ListNode* main) {ListNode* stream = main;ListNode* next = current->next;while(next != NULL) {current = next;next = current->next;}return flow;}// Combine k sorted lists: main functionListNode* mergeKSortedLists(vector& blade) {if(list.size() == 0) {returner NULL;}// combine all k sorted linked lists into one listfor(int i = 0; i < list.size() - 1; i++) {// get the last nodeListNode* last = getLastNode(lister[i]);last->next = lists[i + 1];}// perform a merge sort on the list return sortList(list);}// sort of merge two listsListNode* mergelist(ListNode *l1, ListNode *l2) {ListNode *ptr = new ListNode(0);ListNode *current = ptr;while(l1 != NULL && l2 != NULL) {if(l1->value <= l2->value) {current->next = l1;11 = 11->next;} Ellers {stream->next = l2;l2 = l2->następny;}stream = stream->next;}if(l1 != NULL) {current->next = l1;11 = 11->next;}if(l2 != NULL) {stream->next = l2;l2 = l2->następny;}return ptr->next;}ListNode* sortList(ListNode* main) {if(header == NULL || header->next == NULL)back of head;ListNode *temp = NULL;ListNode *slow = main;ListNode *fast = main;// splits the list into two halveswhile(quick != NULL && quick->next != NULL) {temperature = slow;slow = slow->next;fast = fast->next->next;}temp->next = NULL;// calls sortList recursively for two listsListNode* l1 = sortList(head);ListNode* l2 = sortList(langsom);// merge list l1 and l2return merges(l1,l2);}`

The second brute force approach to solving the problem comes fromconcatenation of two sorted listsmoment. We combine the first two listsbladezbladeand save the result. We combine the result with the third listbladeand repeat the process k - 1 times.

This method is relatively easy. But the time complexity of this approach isO(n * k)where n is the number of elements to be connected.

The C++ snippet of this approach is as follows:

`// Combine k sorted lists: main functionListNode* mergeKSortedLists(vector& blade) {if(list.size() == 0) {returner NULL;}return mergeKSortedListsHelper(list);}// Helper function to merge k sorted listsListNode* mergeKSortedListsHelper(vector& blade) {int size = list.size();// Subtract from penultimate listfor (int i = 1; i <= size; i++) {mens (sand) {ListNode head1 = blade, head2 = blade[i];// if the list is completeif(head1 == NULL) {Holidays;}if(head1->val >= head2->val) {lists[i] = header2->next;main2->next = main1;lists = main2;} Ellers {// Loop through the first listwhile (header1->next != NULL) {// find exactly this node in the first list// greater than the current node in the second listif (head1->next->val >= head2->val) {lists[i] = header2->next;heading2->next = heading1->next;main1->next = main2;Holidays;}main1 = main1->next;}if(heading1->next == NULL) {lists[i] = header2->next;header2->next = NULL;main1->next = main2;header1->next->next = NULL;Holidays;}}}}return letters ;}`

The time complexity of the above two approaches is very high because we are not using sorted lists. We can optimize the approach by using an additional data structure: Min Heap.

## Method 2: Use the minimum stack

We can optimize the above approach with aMy bowl. The Min Heap root is always the smallest element.

According to the problem formulation, all linked lists are sorted. Therefore, the first item on the list will be the smallest. We add the first elements of all linked lists to the minimum heap. We extract the smallest element, the Min Heap root. After removing the root, we increment the index of the list that the root element belonged to. The next node in this list is added to the min heap. We keep removing the root and adding another node from the lists to the heap until all the lists have gone through and the heap is empty.

This algorithm can also be used to concatenate K sorted arrays. The time complexity of the algorithm isO(n * log(k)). Where n is the number of elements in all lists and k is the number of linked lists. The complexity of space iswell)where k is the minimum heap size.

Let's check the algorithm for this approach.

`- priority queuecompare> currently- for int i = 0; Ja- if lists[i] != NULL- pq.push(table[i])- if it's over- At the end- if pq.empty()- returner NULL- if it's over- ListNode* result = ny ListNode(0)ListNode* property = dump- while loop!pq.empty()- ListNode* current = pq.top()pq.pop()- last->next = currentlast = last->next- if current->next != NULLpq.push(current->next)- if it's over- at the end- return result->next`

Let's check the algorithm in C++ code.

`ListNode* mergeKSortedLists(vector& blade) {priority queuecompare>pq;int k = lists.size();// Push the first nodes of all k lists into the 'pq' priority queueγια (int i = 0; i < k; i++)if (liste[i] != NULL)pq.push(list[i]);if (pq.pusty())returner NULL;ListNode *result = new ListNode(0);ListNode *last = result;// Loop until 'pq' is not emptywhile (!pq.pusty()) {// Get the top "pq" elementListNode* stream = pq.top();pq.pop();// Add the top 'pq' element to the result listlast->next = current;last = last->next;// If the current next node is not NULL, add it to the priority queueif (current->next != NULL) {pq.push(current->next);}}// return the resultreturn results->next;}`

## Method 3: Use divide and conquer

By using Min Heap we reduced the time complexity toO(n * log(k))but it is necessarywell)extra stack space. We can solve this problem in constant space by using the divide and conquer technique.

As mentioned in our Brute force approach, we know how to do itmerge two sorted lists. The idea is to pair k lists and connect each pair in linear time usingO(1)space. After the first iteration, k/2 lists of size 2 * n remain. After the second cycle, k/4 lists remain. We repeat this process until we are left with a list.

Let's check the algorithm first.

`// mergeKLists(vectorand letters)- if list.size() == 0- returner NULL- if it's over- zwróć mergeKListsHelper(lister, lists.size() - 1)// mergeKListsHelper(vector& listy, int last)// Merge lists until there is one list left- loop during last != 0- initialize i = 0, j = last- loop while i < i// merge list i with list j// store the merged result in list i- lists[i] = mergeLists(lists[i], lists[j])- increase i = i++- reduce j = j--- if i >= i- last = me- if it's over- at the end- at the end- return letters// mergeLists(ListNode*l1, ListNode*l2)- set ListNode* main = NULL- if l1 == NULL- retur l2- else if l2 == NULL- return l1- if it's over- if l1->value < l2->value- setting header = l1- set l1 = l1->next-Other things- setting header = l2- set l2 = l2->next- if it's over- set ListNode* p = main- loop under l1 && l2- if l1->value < l2->value- set p->next = l1- set l1 = l1->next-Other things- set p->next = l2- set l2 = l2->next- if it's over- set p = p->next- at the end- if l1 != NULL- p->next = l1-Other things- p->next = l2- if it's over- return header`

The time complexity of the above approach isO(n * log(k)), and the complexity of the space isO(1).

Let's see our solutionsC++,Golang, iJavaScript.

## C++ solution

`class solution {public:ListNode* mergeKLister(vector& blade) {if(list.size() == 0) {returner NULL;}return mergeKListsHelper(lists, lists.size() - 1);}ListNode* mergeKListsHelper(vector& listy, int last) {// Merge lists until there is one list leftwhile (last != 0) {int i = 0, j = last;mens (i < j) {// merge list i with list j// store the merged result in list ilister[i] = mergeLists(lister[i], lister[j]);i++;J--;// last update after connecting all pairsif(i >= j) {last = j;}}}return letters ;}ListNode* mergeLists(ListNode* l1, ListNode* l2) {ListNode* head = NULL;// if any of the lists are empty// return the second list.if(l1 == NULL) {retur l2;} andet if(l2 == NULL) {return l1;}// select the header based on the smaller value of the two lists.if(l1->value < l2->value){main = 11;11 = 11->next;} Ellers {main = l2;l2 = l2->następny;}Listeknude *p;p = head;mens(l1 && l2){if(l1->value < l2->value){p->next = 11;11 = 11->next;} Ellers {p->next = l2;l2 = l2->następny;}p = p->next;}if(l1 != NULL){p->next = 11;} Ellers {p->next = l2;}back of head;}};`

## Golang's solution

`func mergeKLists(lister []*ListNode) *ListNode {if len(sheet) == 0 {return null;}returner mergeKListsHelper(lister, len(lister) - 1)}func mergeKListsHelper(listy []*ListNode, last int) *ListNode {// Merge lists until there is one list leftat end != 0 {i, j := 0, lastfor (i < j) {// merge list i with list j// store the merged result in list ilists[i] = mergeLists(lists[i], lists[j])i++;J--;// last update after connecting all pairsif i >= j {last = me}}}return letters}func mergeLists(l1, l2 *ListNode) *ListNode {var head *ListNodemain = null// if any of the lists are empty// return the second list.if l1 == zero {retur l2} else if l2 == null {return l1}// select a header based on the smaller of the two lists.if(l1.Value < l2.Value){main = 11;11 = 11. Next;} Ellers {main = l2;l2 = l2.}p := headfor l1 != null && l2 != null {αν l1.Val < l2.Val {p.Next = l1l1 = l1.Next} Ellers {p. Next = l2l2 = l2. Derefter}p = p. Next}if l1 != zero {p.Next = l1} Ellers {p. Next = l2}head turn}`

## JavaScript solution

`var mergeKLists = function(lister) {if(list.length === 0) {returner null;}return mergeKListsHelper(lists, lists.length - 1);};var mergeKListsHelper = function(lists, last) {// Merge lists until there is one list leftwhile (last != 0) {let i = 0, j = last;mens (i < j) {// merge list i with list j// store the merged result in list ilister[i] = mergeLists(lister[i], lister[j]);i++;J--;// last update after connecting all pairsif(i >= j) {last = j;}}}return letters ;};var mergeList = function (l1, l2) {let head = null;// if any of the lists are empty// return the second list.if(l1 == nul) {retur l2;} andet if(l2 == null) {return l1;}// select a header based on the smaller of the two lists.if(l1.value < l2.value){main = 11;11 = 11th next;} Ellers {main = l2;l2 = l2. następny;}let p = head;mens(l1 && l2){if(l1.value < l2.value){p.next = 11;11 = 11th next;} Ellers {p next = l2;l2 = l2. następny;}p = p.next;}if(l1!=pusty){p.next = 11;} Ellers {p next = l2;}back of head;};`

Let's run our algorithm to see how the solution works.

`Input: lister = [[1, 4, 5], [1, 3, 4], [2, 6]]// MergeKList's functionStep 1: if list.size() == 03 == 0FAKE WARStep 2: return mergeKListsHelper(lister, lists.size() - 1)mergeKListsHelper(list, 2)// mergeKListsHelperStep 3: loop while last != 02 != 0RIGHTand = 0j = last= 2loop mens i < i0 < 2RIGHTlists[i] = mergeLists(lists[i], lists[j])lists = merge Lists(lists, lists)= scalanie lists([1, 4, 5], [2, 6])// MergeLists([1, 4, 5], [2, 6])Step 4: This function will combine the list and return[1, 2, 4, 5, 6]// mergeKListsHelperTrin 5: i++and = 1J--j = 1if i >= i1 = 1RIGHTlast = melast = 1loop mens i < i1 < 1FAKE WAR// mergeKListsHelperStep 6: loop while last != 01 != 0RIGHTand = 0j = last= 1loop mens i < i0 < 1RIGHTlists[i] = mergeLists(lists[i], lists[j])lists = merge Lists(lists, lists)= scalanie lists([1, 2, 4, 5, 6], [1, 3, 4])// MergeLists([1, 2, 4, 5, 6], [1, 3, 4])Step 7: This function will combine the list and return[1, 1, 2, 3, 4, 4, 5, 6]// mergeKListsHelperTrin 8: i++and = 1J--j = 0if i >= i1 >= 0RIGHTlast = melast = 0loop mens i < i1 < 0FAKE WARStep 9: loop during last != 00 != 0FAKE WARStep 10: return lists[1, 1, 2, 3, 4, 4, 5, 6]`

Top Articles
Latest Posts
Article information

Author: Otha Schamberger

Last Updated: 14/04/2023

Views: 6109

Rating: 4.4 / 5 (55 voted)

Author information

Name: Otha Schamberger

Birthday: 1999-08-15

Address: Suite 490 606 Hammes Ferry, Carterhaven, IL 62290

Phone: +8557035444877

Job: Forward IT Agent

Hobby: Fishing, Flying, Jewelry making, Digital arts, Sand art, Parkour, tabletop games

Introduction: My name is Otha Schamberger, I am a vast, good, healthy, cheerful, energetic, gorgeous, magnificent person who loves writing and wants to share my knowledge and understanding with you.