23. 合并K个升序链表 题目难度(困难)

原题目链接:23. 合并K个升序链表

做题思路

  1. 先了解如何合并两个升序链表
    1.1 首先设置一个哨兵节点prevHead,这个节点的目的是为了方便我们最后找到合并后的链表的头结点,设置为-1,由于链表是有序,如果插入的话,肯定在头部。
  2. 设置一个prev指针,我们只需要维护它的next属性,这个指针的目的是为了串联两条链表。
  3. 比较l1和l2的大小,l1和l2就是两条链表
    3.1 如果l1的值小于等于l2的值,上一个节点的next指向l1,l1指向下一个节点
    3.2 如果l1的值大于l2的值,上一个节点的next指向l2,l2指向下一个节点

我们以,l1链表1->3->6->7,l2链表1->2->4->5->9,为例子进行动画演示

点击这里在B站看动画演示喔

废话不多说,直接上代码

private ListNode mergeTwoLists(ListNode l1,ListNode l2){
     
        if(l1 == null || l2 == null){
        //如果一条链表为空,则返回不空的链表
            return l1 == null ? l2 : l1;
        }

        //准备一个哨兵节点,目的是为了方便返回链表头结点
        ListNode preHead = new ListNode(-1);
        //维护这个prev节点,为了可以把两条链表的元素串联起来
        ListNode prev = preHead;
        while(l1 != null && l2 != null){
     
            if(l1.val <= l2.val){
        //l1节点元素的值小于等于l2节点元素的值
                prev.next = l1;
                l1 = l1.next;
            }else{
       //l1节点元素的值大于l2节点元素的值
                prev.next = l2;
                l2 = l2.next;
            }
            prev = prev.next;
        }
        //在两条链表比较完之后,肯定有一条链表还有剩下的节点没有比较,由于是有序的,可以直接放入后面
        prev.next = l1 == null ? l2 : l1;
        //返回哨兵节点,找到链表头结点
        return preHead.next;
    }

在了解完如何合并两条升序链表之后,依次类推,可以通过不断地调用这个mergeTwoLists方法,去实现合并K条升序链表。
设置一个变量ans来保存已经合并后的链表

废话不多说,直接上代码

 public ListNode mergeKLists(ListNode[] lists) {
     
        //用一个变量ans来保存已经合并后的链表
        ListNode ans = null;
        for(int i = 0; i < lists.length; i++){
     
            //合并两个有序链表
            ans = mergeTwoLists(ans,lists[i]);
        }
        return ans;
    }

所以最终的代码就是

 public ListNode mergeKLists(ListNode[] lists) {
     
        //用一个变量ans来保存已经合并后的链表
        ListNode ans = null;
        for(int i = 0; i < lists.length; i++){
     
            //合并两个有序链表
            ans = mergeTwoLists(ans,lists[i]);
        }
        return ans;
    }

    private ListNode mergeTwoLists(ListNode l1,ListNode l2){
     
        if(l1 == null || l2 == null){
        //如果一条链表为空,则返回不空的链表
            return l1 == null ? l2 : l1;
        }

        //准备一个哨兵节点,目的是为了方便返回链表头结点
        ListNode preHead = new ListNode(-1);
        //维护这个prev节点,为了可以把两条链表的元素串联起来
        ListNode prev = preHead;
        while(l1 != null && l2 != null){
     
            if(l1.val <= l2.val){
        //l1节点元素的值小于等于l2节点元素的值
                prev.next = l1;
                l1 = l1.next;
            }else{
       //l1节点元素的值大于l2节点元素的值
                prev.next = l2;
                l2 = l2.next;
            }
            prev = prev.next;
        }
        //在两条链表比较完之后,肯定有一条链表还有剩下的节点没有比较,由于是有序的,可以直接放入后面
        prev.next = l1 == null ? l2 : l1;
        //返回哨兵节点,找到链表头结点
        return preHead.next;
    }

你可能感兴趣的:(链表,数据结构,java,算法,二叉树)