import java.util.Arrays; import java.util.List; import java.util.PriorityQueue; /* class ListNode { ListNode next; int val; ListNode(int x) { val = x; } } */ //k路归并问题 public class MergKSortedLists { //二路归并,这个算法时间复杂度o(2n) public ListNode mergeTwoLists(ListNode l1, ListNode l2) { ListNode dumy = new ListNode(0); ListNode head = dumy; while (l1 != null && l2 != null) { if (l1.val < l2.val) { dumy.next = l1; l1 = l1.next; } else { dumy.next = l2; l2 = l2.next; } dumy = dumy.next; } if (l1 == null) { dumy.next = l2; } if (l2 == null) { dumy.next = l1; } return head.next; } //利用二路归并进行k路归并,时间复杂度o(2kn),leetcode显示time limits exceeds public ListNode mergeKLists1(ListNode[] lists) { if(lists.length == 0) { return null; } ListNode head = lists[0]; for(int i = 1; i < lists.length; i ++) { head = mergeTwoLists(head, lists[i]); } return head; } //网上看到的很有意思的想法。就把ListNode当做一个整数,这道题,正好看做数组的二路归并排序,不过数组里面的元素是节点 //这种方法显然也是超时的,这种思想,看似是二路归并,其实并不是,粒度不一样。这个算法的时间复杂度也并不是O(nlgn) public ListNode mergerKlists2(ListNode[] lists) { //自顶向下的二路归并,递归 if(lists.length == 0) { return null; } List<ListNode> a = Arrays.asList(lists); return helper(a); } public ListNode helper(List<ListNode> lists) { if(lists.size() == 1) { return lists.get(0); } int len = lists.size(); int mid = len/2; ListNode l1 = helper(lists.subList(0, mid)); ListNode l2 = helper(lists.subList(mid, len)); return mergeTwoLists(l1, l2); } //利用PriorityQueue的特性,也很巧妙,并且AC //算法思想是:比较所有k个数组的头一个元素,找到最小的那一个,然后取出来。 //我们在该最小元素所在的数组取下一个元素,然后重复前面的过程去找最小的那个。这样依次循环直到找到所有的元素。 public ListNode mergeKLists3(ListNode[] lists) { if(lists.length == 0) return null; //由于ListNode并没有实现comparable接口,我们必须自定义排序规则,可实现comparator接口,comparator是函数式接口 //comparable接口是在方法内的,而comparator接口是在方法外的注意区别两者 PriorityQueue<ListNode> queue = new PriorityQueue<>((o1, o2)-> { ListNode l1 = (ListNode)o1; ListNode l2 = (ListNode)o2; return l1.val > l2.val ? 1 : l1.val < l2.val ? -1 : 0; }); ListNode head = new ListNode(0); ListNode p = head; for (ListNode list : lists) { queue.offer(list); } while(!queue.isEmpty()) { ListNode n = queue.poll(); p.next = n; p = p.next; if(n.next!=null) { queue.offer(n.next); } } return head.next; } }
堆排序算法后续补充。。。。
时间: 2024-10-13 16:00:36