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

Posted 青春无敌美少

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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);
    

以上是关于java牛客BM4.合并两个排序的链表 BM5. 合并k个已排序的链表的主要内容,如果未能解决你的问题,请参考以下文章

剑指Offer-Java-合并两个排序的链表

剑指Offer:合并两个排序的链表25

剑指Offer-16.合并两个排序的链表(C++/Java)

《剑指Offer》题目:合并两个排序的链表

剑指offer——合并两个排序的链表

《剑指offer》面试题17 合并两个排序的链表 Java版