合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
- 示例:
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6
我的方案
思路
效率最差但是有效的暴力破解。
算法
先遍历参数ListNode数组的每一个链表,将链表每一个结点都放入新建的list集合中
然后将该集合转换成数组,并对数组排序
最后将排序后的数组遍历,将每一个元素作为结点链接起来,成为一个链表返回
代码
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
ArrayList<Integer> list = new ArrayList<Integer>();
ListNode temp = null;
for(int i =0;i<lists.length;i++){
temp = lists[i];
while(temp!=null){
list.add(temp.val);
temp = temp.next;
}
}
Integer[] tempArr = new Integer[list.size()];
Integer[] arr = list.toArray(tempArr);
Arrays.sort(arr);
if(list.size()==0){
return null;
}
ListNode head= new ListNode(arr[0]);
ListNode point= head;
for(int i =1;i<arr1.length;i++){
point.next = new ListNode(arr[i]);
point= point.next;
}
return head;
}
}
精选方案 分治法
思路
典型的归并分治思想,自底向上,依次合并(可结合归并排序理解,将每个链表理解成排序的值)
- 分治法:
- 分解原问题为若干个子问题,这些子问题是原问题的规模较小的实例;
- 递归求解这些子问题,如果规模足够小,则直接求解;
- 合并这些子问题的解即可得到原问题的解。
算法
代码
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if(lists.length == 0) return null;
//将数组和开始结束最后索引传给solve方法
return solve(lists, 0, lists.length-1);
}
private ListNode solve(ListNode[] arr, int left, int right){
//递归出口,即足够小的问题,当数组中只有一个元素即返回
if(left == right) return arr[left];
//不断找中间点
int mid = (left + right) >> 1;
ListNode lNode = solve(arr, left, mid);
ListNode rNode = solve(arr, mid+1, right);
return merge(lNode, rNode);
}
//合并子问题的解
private ListNode merge(ListNode node1, ListNode node2){
if(node1 == null) return node2;
if(node2 == null) return node1;
if(node1.val < node2.val){
node1.next = merge(node1.next, node2);
return node1;
}else{
node2.next = merge(node1, node2.next);
return node2;
}
}
}
作者:user9827R
链接:https://leetcode-cn.com/problems/merge-k-sorted-lists/solution/he-bing-k-ge-pai-xu-lian-biao-by-user9827r/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
精选方案 优先队列
思路
算法
代码
public ListNode mergeKLists(ListNode[] lists) {
PriorityQueue<ListNode> queue = new PriorityQueue<>(Comparator.comparingInt(node -> node.val));
ListNode dummy = new ListNode(0);
ListNode p = dummy;
queue.addAll(Stream.of(lists).filter(Objects::nonNull).collect(Collectors.toList()));
while (!queue.isEmpty()) {
ListNode node = queue.poll();
p.next = node;
p = p.next;
if (node.next != null)
queue.add(node.next);
}
return dummy.next;
}
作者:jackie-tien
链接:https://leetcode-cn.com/problems/merge-k-sorted-lists/solution/javaban-you-xian-dui-lie-shi-xian-shi-jian-fu-za-d/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。