package com.interview.array; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.PriorityQueue; /** * Given a list of lists. Each element in the list is sorted. Sort the * entire list. * Test cases * One or more lists are empty * All elements in one list are smaller than all elements in another list */ public class ChunkMerge { class Triplet implements Comparable<Triplet>{ int pos; int val; int index; @Override public int compareTo(Triplet o) { if(val <= o.val){ return -1; }else{ return 1; } } } public List<Integer> mergeUsingHeap(List<List<Integer>> chunks){ List<Integer> result = new ArrayList<Integer>(); PriorityQueue<Triplet> queue = new PriorityQueue<Triplet>(); //add first element of every chunk into queue for(int i=0; i < chunks.size(); i++){ Triplet p = new Triplet(); p.pos = i; p.val = chunks.get(i).get(0); p.index = 1; queue.add(p); } while(!queue.isEmpty()){ Triplet p = queue.poll(); result.add(p.val); if(p.index < chunks.get(p.pos).size()){ p.val = chunks.get(p.pos).get(p.index); p.index += 1; queue.add(p); } } return result; } public List<Integer> mergeChunksOfDifferentSize(List<List<Integer>> chunks){ List<Integer> result = new ArrayList<Integer>(); int sum[] = new int[chunks.size()+1]; sum[0] = 0; for(int i =1; i < sum.length;i++){ sum[i] = sum[i-1] + chunks.get(i-1).size(); } for(List<Integer> chunk : chunks){ for(Integer i : chunk){ result.add(i); } } mergeSort(result,0,chunks.size()-1,sum); return result; } private void mergeSort(List<Integer> result,int start,int end,int sum[]){ if(start >= end){ return; } int mid = (start + end)/2; mergeSort(result,start,mid,sum); mergeSort(result,mid+1,end,sum); sortedMerge(result,start,end,sum); } private void sortedMerge(List<Integer> result,int start,int end,int sum[]){ /** * If chunks are of equal size then * i = size*start to (mid+1)*size -1 * j = (mid+1)*size to size*(end+1) */ int mid = (start + end)/2; int i = sum[start]; int j = sum[mid+1]; List<Integer> temp = new ArrayList<Integer>(); while(i < sum[mid+1] && j < sum[end+1]){ if(result.get(i) < result.get(j)){ temp.add(result.get(i)); i++; }else{ temp.add(result.get(j)); j++; } } while(i < sum[mid+1]){ temp.add(result.get(i)); i++; } while(j < sum[end+1]){ temp.add(result.get(j)); j++; } int index = sum[start]; for(int k : temp){ result.set(index, k); index++; } } public static void main(String args[]){ Integer arr1[] = {1,5,6,9,21}; Integer arr2[] = {4,6,11,14}; Integer arr3[] = {-1,0,7}; Integer arr4[] = {-4,-2,11,14,18}; Integer arr5[] = {2,6}; Integer arr6[] = {-5,-2,1,5,7,11,14}; Integer arr7[] = {-6,-1,0,15,17,22,24}; List<Integer> list1 = Arrays.asList(arr1); List<Integer> list2 = Arrays.asList(arr2); List<Integer> list3 = Arrays.asList(arr3); List<Integer> list4 = Arrays.asList(arr4); List<Integer> list5 = Arrays.asList(arr5); List<Integer> list6 = Arrays.asList(arr6); List<Integer> list7 = Arrays.asList(arr7); List<List<Integer>> chunks = new ArrayList<List<Integer>>(); chunks.add(list1); chunks.add(list2); chunks.add(list3); chunks.add(list4); chunks.add(list5); chunks.add(list6); chunks.add(list7); ChunkMerge cm = new ChunkMerge(); List<Integer> result = cm.mergeChunksOfDifferentSize(chunks); System.out.println(result.size()); for(Integer r : result){ System.out.print(r + " "); } result = cm.mergeUsingHeap(chunks); System.out.println(); for(Integer r : result){ System.out.print(r + " "); } } }