合并K个排序链表

合并 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;
    }
}

精选方案 分治法

思路

典型的归并分治思想,自底向上,依次合并(可结合归并排序理解,将每个链表理解成排序的值)

  • 分治法:
  1. 分解原问题为若干个子问题,这些子问题是原问题的规模较小的实例;
  2. 递归求解这些子问题,如果规模足够小,则直接求解;
  3. 合并这些子问题的解即可得到原问题的解。
算法
代码
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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值