CodeTop 21/23

这篇博客探讨了如何使用递归和归并排序两种方法来合并两个有序链表,并详细介绍了如何利用优先队列解决合并K个升序链表的问题。递归法中,通过比较头节点值决定合并方向;归并排序则是将链表分为两组,逐步合并;优先队列方案则依赖于小顶堆,快速合并链表并保持升序。
摘要由CSDN通过智能技术生成

21. 合并两个有序链表

递归法:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
 //如果l1或l2为空,无需合并,直接返回非空链表
 //如果l1的值小于l2的值,将l1指向(l1.next,l2)合并后返回的头节点,然后将l1作为本次合并的头节点返回。
class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if(l1==null)    return l2;
        else if(l2==null)   return l1;
        else if(l1.val<=l2.val){
            l1.next=mergeTwoLists(l1.next,l2);
            return l1;
        }else{
            l2.next=mergeTwoLists(l1,l2.next);
            return l2;
        }
    }
}

23. 合并K个升序链表

归并排序:

 //采用分治算法,将链表分为两两一组进行排序
 //数组中的值为链表头节点
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if(lists.length==0) return null;
        return mergeSort(lists, 0, lists.length-1);
    }
    public ListNode mergeSort(ListNode[] lists, int left, int right){
        //如果left=right说明这是数组中同一个头节点,无需进行排序
        if(left==right)
            return lists[left];
        int mid=(left+right)/2;
        //从中点分开,分别对左右两边进行排序,返回排序后的头节点
        ListNode l1=mergeSort(lists, left, mid);
        ListNode l2=mergeSort(lists, mid+1, right);
        //对左右两边链表进行合并操作,在这个过程中对两链表进行排序,返回排序后的链表头
        return merge(l1,l2);
    }
    //用递归法进行合并
    public ListNode merge(ListNode l1, ListNode l2){
        if(l1==null)  return l2;
        if(l2==null)  return l1;
        if(l1.val<=l2.val){
            l1.next=merge(l1.next,l2);
            return l1;
        }else{
            l2.next=merge(l2.next,l1);
            return l2;
        }
    }
}

优先队列:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if(lists.length==0) return null;
        //维护一个优先级队列,小顶堆a-b,大顶堆b-a
        PriorityQueue<ListNode> pq=new PriorityQueue<>((a,b)->a.val-b.val);
        //将数组中的节点依次加入优先级队列中
        for(ListNode node:lists){
            if(node!=null)
                pq.add(node);
        }
        //创建一个伪头节点
        ListNode dummy=new ListNode(0);
        ListNode p=dummy;
        //队列不为空,则执行出队操作,将其连接到升序链表中,然后指向下一个节点
        while(!pq.isEmpty()){
            ListNode tmp=(ListNode)pq.poll();
            p.next=tmp;
            p=p.next;
            if(tmp.next!=null){
                pq.add(tmp.next);
            }
        }
        return dummy.next;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值