LintCode 104:Merge K Sorted Lists(合并K个排序链表)

本文介绍两种高效方法来合并K个已排序的链表。一种是采用归并排序思想,通过递归将链表逐步合并;另一种是利用最小堆(小根堆),不断取出最小元素构建新的排序链表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

合并k个排序链表,并且返回合并后的排序链表。

样例

给出3个排序链表[2->4->null,null,-1->null],返回 -1->2->4->null


分析:

方法一:采用归并排序的思想。数组的数递归划分,一分二,二分四…直至最后一个数单独的成为一组,然后再进行归并划分采用的递归实现。即把K个链表一直对分直到最后一个链表为一组,然后进行递归两两归并,两两归并的操作即成了合并两个排序链表的题。

/**
 * Definition for ListNode.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int val) {
 *         this.val = val;
 *         this.next = null;
 *     }
 * }
 */ 
public class Solution {
    /**
     * @param lists: a list of ListNode
     * @return: The head of one sorted list.
     */
    public ListNode mergeKLists(List<ListNode> lists) {
        // write your code here
        if(lists==null ||lists.size()==0)   return null;
        return MSort(lists,0,lists.size()-1);
    }

    public ListNode MSort(List<ListNode> lists,int low,int high){
        if(low==high)
            return lists.get(low);
        int mid=(low+high)/2;
        ListNode leftlist=MSort(lists,low,mid);
        ListNode rightlist=MSort(lists,mid+1,high);
        return Merge(leftlist,rightlist);
    }
    
    public ListNode Merge(ListNode l1,ListNode l2){
        if(l1==null)    return l2;
        if(l2==null)    return l1;
        ListNode l3;
        if(l1.val<l2.val){
            l3=l1;
            l1=l1.next;
        }else{
            l3=l2;
            l2=l2.next;
        }

        ListNode fakeHead=new ListNode(-1); //创建辅助头结点
        fakeHead.next=l3;
        while(l1!=null&&l2!=null){
            if(l1.val<l2.val){
                l3.next=l1;
                l1=l1.next;
                l3=l3.next;
            }else{
                l3.next=l2;
                l2=l2.next;
                l3=l3.next;
            }
        }
        if(l1==null){
            l3.next=l2;
        }
        if(l2==null){
            l3.next=l1;
        }
        return fakeHead.next;
    }
}

方法二:

使用堆排序(小根堆),把所有头结点放入堆中,每次取出根结点,放到新建头结点的下一个结点,并把取出来的结点的下一个结点放入堆中,直到堆中没有结点。

public ListNode mergeKLists1(List<ListNode> lists) {
        if(lists.size()==0||lists==null)    return null;
        Queue<ListNode> heap=new PriorityQueue<>(lists.size(), new Comparator<ListNode>() {
            @Override
            public int compare(ListNode o1, ListNode o2) {
                return o1.val-o2.val;
            }
        });
        //把头结点放入堆中
        for(int i=0;i<lists.size();i++){
            if(lists.get(i)!=null)
                heap.add(lists.get(i));
        }
        //新建头结点
        ListNode dummy=new ListNode(-1);
        //每次把堆中的根结点取出,接到头结点之后
        ListNode cur=dummy;
        while(heap.size()>0){
            ListNode head=heap.poll();
            cur.next=head;
            cur=head;
            if(head.next!=null){
                heap.add(head.next);
            }
        }
        return dummy.next;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值