合并K个有序链表
2017-10-17 16:40
253 查看
1.利用堆的特性
import java.util.ArrayList; import java.util.Comparator; import java.util.LinkedList; import java.util.PriorityQueue; class Node { public Integer value; public Node next;// 指向下一个节点 public Node(int value) { this.value=value; } } public class KSortedLinkedList { static PriorityQueue<Node> queue = new PriorityQueue<Node>(new Comparator<Node>() { @Override public int compare(Node o1, Node o2) { return o1.value -o2.value; } }); public static void just(LinkedList<Node> list) { if (list != null && list.size() != 0) { for (int i = 0; i < list.size() - 1; i++) { list.get(i).next = list.get(i + 1); } list.get(list.size() - 1).next = null; } } public static void sort(LinkedList<Node>[] kList) { ArrayList<Integer> newList = new ArrayList<Integer>(); //首先将k个LinkedList的每个header部分放到queue中 for (LinkedList<Node> list : kList) { if (list.isEmpty() == false) queue.offer(list.pop()); } while (queue.isEmpty() == false) { Node node=queue.poll(); newList.add(node.value); //将node的下一个节点添加到queue中 if(node.next != null) { queue.add(node.next); } } for (int n : newList) { System.out.print(n + " "); } } public static void main(String[] args) { LinkedList<Node>[] kList = new LinkedList[4]; kList[0] = new LinkedList<Node>(); kList[1] = new LinkedList<Node>(); kList[2] = new LinkedList<Node>(); kList[3] = new LinkedList<Node>(); kList[0].add(new Node(-11)); kList[0].add(new Node(-3)); kList[0].add(new Node(5)); kList[0].add(new Node(7)); kList[1].add(new Node(2)); kList[1].add(new Node(14)); kList[1].add(new Node(16)); kList[1].add(new Node(28)); kList[2].add(new Node(28)); kList[2].add(new Node(29)); kList[2].add(new Node(30)); kList[3].add(new Node(29)); kList[3].add(new Node(52)); just(kList[0]); just(kList[1]); just(kList[2]); just(kList[3]); sort(kList); } }
如果K个排序的LinkedList中的元素是按照大小逆序排序的,只需要将compare改为o2.value -o1.value.
关键点分析:
PriorityQueue是一个堆,默认是最小堆。
An unbounded priority {@linkplain Queue queue} based on a priority heap.
首先将k个已经排序的LinkedList的header放到最小堆中,然后取出堆顶的元素,即最小的元素,再把刚取出元素的后面一个元素放到堆中,以此类推循环。这里,使用“指针”的方式,很便捷,假设不用这种指针方式,还真不好处理。
2.分治算法
import java.util.LinkedList; public class KSortedLinkedList2 { public static LinkedList<Integer> mergeK(LinkedList<Integer>[] listArr,int low,int high){ if(low==high) return listArr[low]; if(high-low==1) return merge2(listArr[low],listArr[high]); int mid=(low+high) / 2; LinkedList<Integer> list1=mergeK(listArr,low,mid); LinkedList<Integer> list2=mergeK(listArr,mid+1,high); return merge2(list1,list2); } public static LinkedList<Integer> merge2(LinkedList<Integer> list1 , LinkedList<Integer> list2) { LinkedList<Integer> newList=new LinkedList<Integer>(); int i=0,j=0; for(;i<list1.size() && j<list2.size();) { if(list1.get(i)<=list2.get(j)) { newList.add(list1.get(i)); i++; }else { newList.add(list2.get(j)); j++; } } if(i<list1.size()) { while(i<list1.size()) { newList.add(list1.get(i)); i++; } } if(j<list2.size()) { while(j<list2.size()) { newList.add(list2.get(j)); j++; } } return newList; } public static void main(String[] args) { LinkedList<Integer> list1=new LinkedList<Integer>(); list1.add(1); list1.add(3); list1.add(7); list1.add(10); list1.add(16); LinkedList<Integer> list2=new LinkedList<Integer>(); list2.add(0); list2.add(4); list2.add(9); LinkedList<Integer> list3=new LinkedList<Integer>(); list3.add(2); list3.add(6); list3.add(21); LinkedList<Integer> list4=new LinkedList<Integer>(); list4.add(-2); list4.add(12); list4.add(22); LinkedList<Integer>[] listArr=new LinkedList[4]; listArr[0]=list1; listArr[1]=list2; listArr[2]=list3; listArr[3]=list4; LinkedList<Integer> newList=mergeK(listArr,0,listArr.length-1); for (int n : newList) { System.out.print(n + " "); } } }
参考链接:
http://blog.csdn.net/mine_song/article/details/69501383
https://www.2cto.com/kf/201606/514246.html
相关文章推荐
- Leet Code 23 Merge k Sorted Lists - 合并K个有序链表 Java
- 算法导论第三版第六章 合并K个有序链表的三种解法(最小堆法和分治递归法)
- 合并k个有序链表 Merge k Sorted Lists
- leetcode_效率题解_23. Merge k Sorted Lists(合并k个有序链表)
- [LeetCode] 23. Merge k Sorted Lists 合并k个有序链表
- [itint5]合并K个有序链表
- 经典算法——合并K个有序链表
- 合并K个有序链表-堆的使用
- [LeetCode] Merge k Sorted Lists 合并k个有序链表
- LeetCode 23.Merge k Sorted List 合并k个有序链表(后补)
- 合并k个有序链表
- K个有序链表共N个结点在O(NlgK)时间合并为一个新的有序链表头文件C语言
- 23. Merge k Sorted Lists 合并K个有序链表
- [LeetCode23]Merge k Sorted Lists(合并k个有序链表)
- K个有序链表共N个结点在O(NlgK)时间合并为一个新的有序链表实现文件C语言
- leetcode解题之23.Merge k Sorted Lists Java版本(合并k个有序的链表)
- 【算法】合并k个有序的链表-基于最小堆的思想
- 在O(N lgK) 时间内合并K个有序链表
- 链表面试题(二):冒泡排序、合并两个有序链表、查找中间节点、查找倒数K个节点
- 将k个有序链表合并成一个有序链表