k路归并:数组、链表
/** * 解法1:逐个合并数组,时间复杂度O(n*k),n >> k * 合并k个排序(升序)数组 * http://www.lintcode.com/zh-cn/problem/merge-k-sorted-arrays/ * @author yzwall */ class Solution { public List<Integer> mergekSortedArrays(int[][] arrays) { ArrayList<Integer> list = new ArrayList<Integer>(); if (arrays == null || arrays.length == 0 || arrays[0].length == 0) { return list; } if (arrays.length == 1) { Arrays.sort(arrays[0]); for (int num : arrays[0]) { list.add(num); } return list; } int[] temp = mergeTwoArrays(arrays[0], arrays[1]); for (int i = 2; i < arrays.length; i++) { temp = mergeTwoArrays(temp, arrays[i]); } for (int num : temp) { list.add(num); } return list; } private int[] mergeTwoArrays(int[] A, int[] B) { if (A.length == 0 || B.length == 0) { return new int[0]; } int[] temp = new int[A.length + B.length]; int index = 0, i = 0, j = 0; while (i < A.length && j < B.length) { if (A[i] < B[j]) { temp[index++] = A[i++]; } else { temp[index++] = B[j++]; } } while (i < A.length) { temp[index++] = A[i++]; } while (j < B.length) { temp[index++] = B[j++]; } return temp; } } /** * 解法2:分治法K路归并,时间复杂度O(n logk) * 合并k个排序(升序)数组 * http://www.lintcode.com/zh-cn/problem/merge-k-sorted-arrays/ * @author yzwall */ class Solution20 { public List<Integer> mergekSortedArrays(int[][] arrays) { ArrayList<Integer> list = new ArrayList<Integer>(); if (arrays == null || arrays.length == 0 || arrays[0].length == 0) { return list; } int[] ans = kMergeSort(arrays, 0, arrays.length - 1); for (int num : ans) { list.add(num); } return list; } // 分治递归深度为O(log k), 每层合并时间复杂度O(n) private int[] kMergeSort(int[][] arrays, int start, int end) { if (start >= end) { return arrays[start]; } int mid = start + (end - start) / 2; int[] left = kMergeSort(arrays, start, mid); int[] right = kMergeSort(arrays, mid + 1, end); return mergeTwoArrays(left, right); } private int[] mergeTwoArrays(int[] A, int[] B) { int[] temp = new int[A.length + B.length]; int index = 0, i = 0, j = 0; while (i < A.length && j < B.length) { if (A[i] < B[j]) { temp[index++] = A[i++]; } else { temp[index++] = B[j++]; } } while (i < A.length) { temp[index++] = A[i++]; } while (j < B.length) { temp[index++] = B[j++]; } return temp; } } /** * 解法3:最小堆实现K路归并,时间复杂度O(n logk) * 合并k个排序(升序)数组 * http://www.lintcode.com/zh-cn/problem/merge-k-sorted-arrays/ * @author yzwall */ class Solution18 { private class NewInteger { int value, row, col; public NewInteger(int value, int row, int col) { this.value = value; this.row = row; this.col = col; } } public List<Integer> mergekSortedArrays(int[][] arrays) { ArrayList<Integer> list = new ArrayList<Integer>(); if (arrays == null || arrays.length == 0 || arrays[0].length == 0) { return list; } PriorityQueue<NewInteger> pq = new PriorityQueue<>(arrays.length, new Comparator<NewInteger>() { public int compare(NewInteger o1, NewInteger o2) { return o1.value < o2.value ? -1 : 1; } }); for (int i = 0; i < arrays.length; i++) { pq.offer(new NewInteger(arrays[i][0], i, 0)); } while (!pq.isEmpty()) { NewInteger min = pq.poll(); if (min.col + 1 < arrays[min.row].length) { pq.offer(new NewInteger(arrays[min.row][min.col + 1], min.row, min.col + 1)); } list.add(min.value); } return list; } } /** * 解法4:暴力方法,将所有数组添加到List,统一排序,时间复杂度O(n*k + nlogn), n >> k * 合并k个排序(升序)数组 * http://www.lintcode.com/zh-cn/problem/merge-k-sorted-arrays/ * @author yzwall */ class Solution19 { public List<Integer> mergekSortedArrays(int[][] arrays) { ArrayList<Integer> list = new ArrayList<Integer>(); if (arrays == null || arrays.length == 0 || arrays[0].length == 0) { return list; } for (int i = 0; i < arrays.length; i++) { addToList(list, arrays[i]); } Collections.sort(list); return list; } private void addToList(ArrayList<Integer>list, int[] nums) { for (int num : nums) { list.add(num); } } }
上面的代码转载自:K路归并问题小结
在LeetCode 23中是合并k路链表
23. Merge k Sorted Lists
自己的代码如下,采用的是优先级队列
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { private class MinHeapComparator implements Comparator<ListNode>{ public int compare(ListNode node1, ListNode node2){ return node1.val - node2.val; } } public ListNode mergeKLists(ListNode[] lists) { ListNode res = new ListNode(0); if(lists.length <= 0) return null; if(lists.length == 1) return lists[0]; PriorityQueue<ListNode> queue = new PriorityQueue<>(new MinHeapComparator()); for(int i = 0; i < lists.length; i++){ if(lists[i] != null) queue.offer(lists[i]); } ListNode node = res; while(!queue.isEmpty()){ ListNode littleNode = queue.poll(); node.next = littleNode; node = node.next; if(littleNode.next != null) queue.offer(littleNode.next); } return res.next; } }