Given a 2D matrix, mat[][] of size n x m consisting of sorted arrays, where each row is sorted in non-decreasing order, find a single sorted array that contains all the elements from the matrix.
[Naive Approach] Merge All Elements and Sort - O(n × m log(n × m))
The idea is to merges sorted arrays by first flattening all the arrays into a single one-dimensional vector. Then sorts this combined vector using the standard sorting algorithm (sort() from the STL). This ensures the final result is a fully sorted array containing all elements from the input arrays.
C++
#include<iostream>#include<algorithm>#include<vector>usingnamespacestd;vector<int>mergeArrays(vector<vector<int>>&mat){vector<int>res;// Append all arrays into resfor(constauto&vec:mat){for(intval:vec)res.push_back(val);}// Sort the ressort(res.begin(),res.end());returnres;}intmain(){vector<vector<int>>mat={{1,3,5,7},{2,4,6,8},{0,9,10,11}};vector<int>res=mergeArrays(mat);for(intval:res){cout<<val<<" ";}return0;}
Java
importjava.util.ArrayList;importjava.util.Collections;classGFG{staticArrayList<Integer>mergeArrays(int[][]mat){ArrayList<Integer>res=newArrayList<>();// Append all arrays into resfor(inti=0;i<mat.length;i++){for(intj=0;j<mat[i].length;j++){res.add(mat[i][j]);}}// Sort the resCollections.sort(res);returnres;}publicstaticvoidmain(String[]args){int[][]mat={{1,3,5,7},{2,4,6,8},{0,9,10,11}};ArrayList<Integer>res=mergeArrays(mat);for(intval:res){System.out.print(val+" ");}}}
Python
defmergeArrays(mat):res=[]# Append all arrays into resforvecinmat:forvalinvec:res.append(val)# Sort the resres.sort()returnresif__name__=="__main__":mat=[[1,3,5,7],[2,4,6,8],[0,9,10,11]]res=mergeArrays(mat)print(*res)
C#
usingSystem;usingSystem.Collections.Generic;classGFG{staticList<int>mergeArrays(int[,]mat){List<int>res=newList<int>();introws=mat.GetLength(0);intcols=mat.GetLength(1);// Append all elements into resfor(inti=0;i<rows;i++){for(intj=0;j<cols;j++){res.Add(mat[i,j]);}}// Sort the resres.Sort();returnres;}staticvoidMain(){int[,]mat=newint[,]{{1,3,5,7},{2,4,6,8},{0,9,10,11}};List<int>res=mergeArrays(mat);foreach(intvalinres){Console.Write(val+" ");}}}
JavaScript
functionmergeArrays(mat){letres=[];// Append all arrays into resfor(letvecofmat){for(letvalofvec){res.push(val);}}// Sort the resres.sort((a,b)=>a-b);returnres;}// Driver codeletmat=[[1,3,5,7],[2,4,6,8],[0,9,10,11]];letres=mergeArrays(mat);console.log(res.join(" "));
Output
0 1 2 3 4 5 6 7 8 9 10 11
[Expected Approach] Using Merge Sort - Works Better for Equal Sized Arrays - O(n × m log n) Time and O(n × m) Space
The idea is to use the Divide and Conquer approach, similar to Merge Sort. We keep dividing the given sorted arrays into smaller groups until we are left with single array. Then, we start merging these single arrays upward in sorted order, gradually combining them until one fully sorted array remains.
C++
#include<iostream>#include<vector>usingnamespacestd;// Function to merge two sorted arraysvector<int>concat(vector<int>&a,vector<int>&b){inti=0,j=0;intn1=a.size(),n2=b.size();vector<int>c;c.reserve(n1+n2);// Merge both arrays in sorted orderwhile(i<n1&&j<n2){if(a[i]<b[j])c.push_back(a[i++]);elsec.push_back(b[j++]);}// Add remaining elements of first arraywhile(i<n1)c.push_back(a[i++]);// Add remaining elements of second arraywhile(j<n2)c.push_back(b[j++]);returnc;}// Recursively merge K sorted arrays using divide and conquervector<int>merge(vector<vector<int>>&mat,intlo,inthi){// Base caseif(lo==hi)returnmat[lo];// Divide arrays into two halvesintmid=(lo+hi)/2;// Merge left halfvector<int>left=merge(mat,lo,mid);// Merge right halfvector<int>right=merge(mat,mid+1,hi);// Combine both halvesreturnconcat(left,right);}// merge all K sorted arraysvector<int>mergeArrays(vector<vector<int>>&mat){intk=mat.size();if(k==0)return{};returnmerge(mat,0,k-1);}intmain(){vector<vector<int>>mat={{1,3,5,7},{2,4,6,8},{0,9,10,11}};intk=mat.size();vector<int>res=mergeArrays(mat);for(intval:res)cout<<val<<" ";cout<<endl;return0;}
Java
importjava.util.ArrayList;classGFG{// Function to merge two sorted arraysstaticArrayList<Integer>concat(ArrayList<Integer>a,ArrayList<Integer>b){inti=0,j=0;intn1=a.size(),n2=b.size();ArrayList<Integer>c=newArrayList<>();// Merge both arrays in sorted orderwhile(i<n1&&j<n2){if(a.get(i)<b.get(j))c.add(a.get(i++));elsec.add(b.get(j++));}// Add remaining elements of first arraywhile(i<n1)c.add(a.get(i++));// Add remaining elements of second arraywhile(j<n2)c.add(b.get(j++));returnc;}// Recursively merge K sorted arrays using divide and conquerstaticArrayList<Integer>merge(ArrayList<ArrayList<Integer>>mat,intlo,inthi){// Base caseif(lo==hi)returnmat.get(lo);// Divide arrays into two halvesintmid=(lo+hi)/2;// Merge left halfArrayList<Integer>left=merge(mat,lo,mid);// Merge right halfArrayList<Integer>right=merge(mat,mid+1,hi);// Combine both halvesreturnconcat(left,right);}// merge all K sorted arraysstaticArrayList<Integer>mergeArrays(int[][]mat){intk=mat.length;if(k==0)returnnewArrayList<>();// Convert 2D array to ArrayList<ArrayList<Integer>>ArrayList<ArrayList<Integer>>list=newArrayList<>();for(inti=0;i<k;i++){ArrayList<Integer>temp=newArrayList<>();for(intj=0;j<mat[i].length;j++){temp.add(mat[i][j]);}list.add(temp);}returnmerge(list,0,k-1);}publicstaticvoidmain(String[]args){int[][]mat={{1,3,5,7},{2,4,6,8},{0,9,10,11}};ArrayList<Integer>res=mergeArrays(mat);for(intval:res)System.out.print(val+" ");System.out.println();}}
Python
# Function to merge two sorted arraysdefconcat(a,b):i=0j=0n1=len(a)n2=len(b)c=[]# Merge both arrays in sorted orderwhilei<n1andj<n2:ifa[i]<b[j]:c.append(a[i])i+=1else:c.append(b[j])j+=1# Add remaining elements of first arraywhilei<n1:c.append(a[i])i+=1# Add remaining elements of second arraywhilej<n2:c.append(b[j])j+=1returnc# Recursively merge K sorted arrays using divide and conquerdefmerge(mat,lo,hi):# Base caseiflo==hi:returnmat[lo]# Divide arrays into two halvesmid=(lo+hi)//2# Merge left halfleft=merge(mat,lo,mid)# Merge right halfright=merge(mat,mid+1,hi)# Combine both halvesreturnconcat(left,right)# merge all K sorted arraysdefmergeArrays(mat):k=len(mat)ifk==0:return[]returnmerge(mat,0,k-1)if__name__=="__main__":mat=[[1,3,5,7],[2,4,6,8],[0,9,10,11]]k=len(mat)res=mergeArrays(mat)forvalinres:print(val,end=" ")print()
C#
usingSystem;usingSystem.Collections.Generic;classGFG{// Function to merge two sorted arraysstaticList<int>concat(List<int>a,List<int>b){inti=0,j=0;intn1=a.Count,n2=b.Count;List<int>c=newList<int>(n1+n2);// Merge both arrays in sorted orderwhile(i<n1&&j<n2){if(a[i]<b[j])c.Add(a[i++]);elsec.Add(b[j++]);}// Add remaining elements of first arraywhile(i<n1)c.Add(a[i++]);// Add remaining elements of second arraywhile(j<n2)c.Add(b[j++]);returnc;}// Recursively merge K sorted arrays using divide and conquerstaticList<int>merge(List<List<int>>mat,intlo,inthi){// Base caseif(lo==hi)returnmat[lo];// Divide arrays into two halvesintmid=(lo+hi)/2;// Merge left halfList<int>left=merge(mat,lo,mid);// Merge right halfList<int>right=merge(mat,mid+1,hi);// Combine both halvesreturnconcat(left,right);}// merge all K sorted arraysstaticList<int>mergeArrays(int[,]mat){intk=mat.GetLength(0);if(k==0)returnnewList<int>();intnCols=mat.GetLength(1);// Convert 2D array to List<List<int>>List<List<int>>list=newList<List<int>>();for(inti=0;i<k;i++){List<int>temp=newList<int>();for(intj=0;j<nCols;j++){temp.Add(mat[i,j]);}list.Add(temp);}returnmerge(list,0,k-1);}staticvoidMain(string[]args){int[,]mat=newint[,]{{1,3,5,7},{2,4,6,8},{0,9,10,11}};List<int>res=mergeArrays(mat);foreach(intvalinres)Console.Write(val+" ");Console.WriteLine();}}
JavaScript
// Function to merge two sorted arraysfunctionconcat(a,b){leti=0,j=0;letn1=a.length,n2=b.length;letc=[];// Merge both arrays in sorted orderwhile(i<n1&&j<n2){if(a[i]<b[j])c.push(a[i++]);elsec.push(b[j++]);}// Add remaining elements of first arraywhile(i<n1)c.push(a[i++]);// Add remaining elements of second arraywhile(j<n2)c.push(b[j++]);returnc;}// Recursively merge K sorted arrays using divide and conquerfunctionmerge(mat,lo,hi){// Base caseif(lo===hi)returnmat[lo];// Divide arrays into two halvesletmid=Math.floor((lo+hi)/2);// Merge left halfletleft=merge(mat,lo,mid);// Merge right halfletright=merge(mat,mid+1,hi);// Combine both halvesreturnconcat(left,right);}// merge all K sorted arraysfunctionmergeArrays(mat){letk=mat.length;if(k===0)return[];returnmerge(mat,0,k-1);}// Driver codeletmat=[[1,3,5,7],[2,4,6,8],[0,9,10,11]];letk=mat.length;letres=mergeArrays(mat);console.log(res.join(' '));
Output
0 1 2 3 4 5 6 7 8 9 10 11
[Alternative Approach] Using Min-Heap - Works better for Different Sized Arrays - O(n × m log n) Time and O(n × m) Space
The idea is to merge sorted arrays using a Min Heap. We start by inserting the first element of each array into the heap. The smallest element is always at the top, so we remove it and add it to the output array. Then we insert the next element from the same array into the heap. We repeat this process until the heap is empty. This ensures that we always pick the smallest available element, producing a fully sorted merged array efficiently.
C++
#include<iostream>#include<queue>#include<vector>usingnamespacestd;vector<int>mergeArrays(vector<vector<int>>&mat){intk=mat.size();vector<int>res;// Min-heap: {value, {array index, element index}}priority_queue<pair<int,pair<int,int>>,vector<pair<int,pair<int,int>>>,greater<pair<int,pair<int,int>>>>minHeap;// Push first element of each arrayfor(inti=0;i<k;++i){if(!mat[i].empty()){minHeap.push({mat[i][0],{i,0}});}}// Merge all elementswhile(!minHeap.empty()){autotop=minHeap.top();minHeap.pop();intval=top.first;inti=top.second.first;intj=top.second.second;res.push_back(val);// Push next element from same arrayif(j+1<mat[i].size()){minHeap.push({mat[i][j+1],{i,j+1}});}}returnres;}intmain(){vector<vector<int>>mat={{1,3,5,7},{2,4,6,8},{0,9,10,11}};vector<int>result=mergeArrays(mat);for(intx:result){cout<<x<<" ";}cout<<endl;return0;}
Java
importjava.util.ArrayList;importjava.util.List;importjava.util.PriorityQueue;importjava.util.Comparator;classGFG{staticArrayList<Integer>mergeArrays(int[][]mat){intk=mat.length;ArrayList<Integer>res=newArrayList<>();// Min-heap: {value, {array index, element index}}PriorityQueue<int[]>minHeap=newPriorityQueue<>(Comparator.comparingInt(a->a[0]));// Push first element of each arrayfor(inti=0;i<k;++i){if(mat[i].length>0){minHeap.add(newint[]{mat[i][0],i,0});}}// Merge all elementswhile(!minHeap.isEmpty()){int[]top=minHeap.poll();intval=top[0];inti=top[1];intj=top[2];res.add(val);// Push next element from same arrayif(j+1<mat[i].length){minHeap.add(newint[]{mat[i][j+1],i,j+1});}}returnres;}publicstaticvoidmain(String[]args){int[][]mat={{1,3,5,7},{2,4,6,8},{0,9,10,11}};ArrayList<Integer>result=mergeArrays(mat);for(intx:result){System.out.print(x+" ");}System.out.println();}}
Python
importheapqdefmergeArrays(mat):k=len(mat)res=[]# Min-heap: (value, (array index, element index))minHeap=[]# Push first element of each arrayforiinrange(k):iflen(mat[i])>0:heapq.heappush(minHeap,(mat[i][0],i,0))# Merge all elementswhileminHeap:val,i,j=heapq.heappop(minHeap)res.append(val)# Push next element from same arrayifj+1<len(mat[i]):heapq.heappush(minHeap,(mat[i][j+1],i,j+1))returnresif__name__=="__main__":mat=[[1,3,5,7],[2,4,6,8],[0,9,10,11]]result=mergeArrays(mat)print(" ".join(map(str,result)))
C#
usingSystem;usingSystem.Collections.Generic;// Custom Min-Heap Priority QueueclassMinHeap{privateList<(intval,intarrIdx,intelemIdx)>heap;publicMinHeap(){heap=newList<(int,int,int)>();}privatevoidSwap(inti,intj){vartemp=heap[i];heap[i]=heap[j];heap[j]=temp;}privatevoidHeapifyUp(intindex){while(index>0){intparent=(index-1)/2;if(heap[index].val<heap[parent].val){Swap(index,parent);index=parent;}elsebreak;}}privatevoidHeapifyDown(intindex){intlast=heap.Count-1;while(true){intleft=2*index+1;intright=2*index+2;intsmallest=index;if(left<=last&&heap[left].val<heap[smallest].val)smallest=left;if(right<=last&&heap[right].val<heap[smallest].val)smallest=right;if(smallest!=index){Swap(index,smallest);index=smallest;}elsebreak;}}publicvoidAdd((intval,intarrIdx,intelemIdx)item){heap.Add(item);HeapifyUp(heap.Count-1);}public(intval,intarrIdx,intelemIdx)Pop(){vartop=heap[0];heap[0]=heap[heap.Count-1];heap.RemoveAt(heap.Count-1);HeapifyDown(0);returntop;}publicintCount(){returnheap.Count;}}classGFG{staticList<int>mergeArrays(int[,]mat){intk=mat.GetLength(0);intnCols=mat.GetLength(1);List<int>res=newList<int>();// Min-heap: {value, array index, element index}MinHeapminHeap=newMinHeap();// Push first element of each arrayfor(inti=0;i<k;i++){if(nCols>0)minHeap.Add((mat[i,0],i,0));}// Merge all elementswhile(minHeap.Count()>0){vartop=minHeap.Pop();intval=top.val;inti=top.arrIdx;intj=top.elemIdx;res.Add(val);// Push next element from same arrayif(j+1<nCols)minHeap.Add((mat[i,j+1],i,j+1));}returnres;}staticvoidMain(){int[,]mat=newint[,]{{1,3,5,7},{2,4,6,8},{0,9,10,11}};List<int>result=mergeArrays(mat);foreach(intxinresult)Console.Write(x+" ");Console.WriteLine();}}
JavaScript
// Custom Min-Heap Priority QueueclassMinHeap{constructor(){this.heap=[];}swap(i,j){[this.heap[i],this.heap[j]]=[this.heap[j],this.heap[i]];}heapifyUp(index){while(index>0){letparent=Math.floor((index-1)/2);if(this.heap[index][0]<this.heap[parent][0]){this.swap(index,parent);index=parent;}elsebreak;}}heapifyDown(index){letlast=this.heap.length-1;while(true){letleft=2*index+1;letright=2*index+2;letsmallest=index;if(left<=last&&this.heap[left][0]<this.heap[smallest][0])smallest=left;if(right<=last&&this.heap[right][0]<this.heap[smallest][0])smallest=right;if(smallest!==index){this.swap(index,smallest);index=smallest;}elsebreak;}}add(item){this.heap.push(item);this.heapifyUp(this.heap.length-1);}pop(){consttop=this.heap[0];this.heap[0]=this.heap[this.heap.length-1];this.heap.pop();this.heapifyDown(0);returntop;}size(){returnthis.heap.length;}}functionmergeArrays(mat){letk=mat.length;letres=[];// Min-heap: [value, array index, element index]constminHeap=newMinHeap();// Push first element of each arrayfor(leti=0;i<k;i++){if(mat[i].length>0){minHeap.add([mat[i][0],i,0]);}}// Merge all elementswhile(minHeap.size()>0){let[val,i,j]=minHeap.pop();res.push(val);// Push next element from same arrayif(j+1<mat[i].length){minHeap.add([mat[i][j+1],i,j+1]);}}returnres;}// Driver codeletmat=[[1,3,5,7],[2,4,6,8],[0,9,10,11]];letresult=mergeArrays(mat);console.log(result.join(' '));