【java】牛客BM4.合并两个排序的链表 BM5. 合并k个已排序的链表

合并 k 个升序的链表并将结果作为一个升序的链表返回其头节点。
输入:[{1,2,3},{4,5,6,7}]
返回值:{1,2,3,4,5,6,7}

解题思路

合并排序两个有序链表

在做类似这种排序题时,我们可以先从简单一点的题型入手解决。
首先,我们一起来学习合并排序两个有序链表
我来说两种做法。

1.迭代

首先新建立一个放置于新链表前的哑节点head,最后返回的是head.next。
设置cur为当前节点,从head开始向后增加节点。当两个链表都非空时进入循环,令新链表的下一个节点cur.next为val更小的节点,同时该链表的此节点后移一位,每次循环cur也要后移一位。
如果循环结束后还有链表非空,cur指向非空链表,返回head.next。

 public ListNode Merge(ListNode list1, ListNode list2) {
        //当其中一个为空时,返回另一个
        if(list1==null||list2==null)
        return list1!=null?list1:list2;
        //加一个表头
        ListNode head = new ListNode(0);
        ListNode cur = head;
        //两个链表都要不为空
        while(list1 != null && list2 != null){
            //取较小值的节点
            if(list1.val <= list2.val){
                cur.next = list1;
                //只移动取值的指针
                list1 = list1.next;
            }else{
                cur.next = list2;
                //只移动取值的指针
                list2 = list2.next;
            }
            //指针后移
            cur = cur.next;
        }
        //哪个链表还有剩,直接连在后面
        cur.next=list1!=null?list1:list2;
        //返回值去掉表头
        return head.next;
    }

2.递归

首先,我们还是要考虑有链表为空时的情况。当其中一个链表为空时,返回另一个链表。
如果list1 结点值比小list2,下一个结点应该是 list1,应该return list1,在return之前,指定list1的下一个结点应该是list1.next和list2俩链表的合并后的头结点
如果list1 结点值比list2大,下一个结点应该是list2,应该return list2,在return之前,指定list2的下一个结点应该是list1和list2.next俩链表的合并后的头结点。

    public ListNode Merge(ListNode ç,ListNode list2) {
       // list1 list2为空的情况
       if(list1 == null || list2 == null){
           return list1 != null ? list1 : list2;
       }
       // 两个链表元素依次对比
       if(list1.val <= list2.val){
           // 递归计算 list1.next, list2
           list1.next = Merge(list1.next, list2);
           return list1;
       }else{
           // 递归计算 list1, list2.next
           list2.next = Merge(list1, list2.next);
           return list2;
       } 
   }

合并k个有序链表

此题利用归并的解题思路,先将其分为俩个链表,范围为[0,mid],[mid+1,lists.size()-1],再使用合并2个有序链表的方法进行排序。

public class Solution {
    public ListNode Merge(ListNode list1,ListNode list2){
        if(list1==null||list2==null)
        return list1==null?list2:list1;
        else{
            if(list1.val<list2.val){
                list1.next=Merge(list1.next,list2);
                return list1;
            }
            else{
                list2.next=Merge(list1,list2.next);
                return list2;
            }
        }
    }
    public ListNode divideMerge(ArrayList<ListNode> lists,int left,int right){
        if(left>right)
        return null;
        else if(left==right)
        return lists.get(left);
        int mid=(left+right)/2;
        return Merge(divideMerge(lists,left,mid),divideMerge(lists,mid+1,right));

    }
    public ListNode mergeKLists(ArrayList<ListNode> lists) {
        return divideMerge(lists,0,lists.size()-1);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值