合并两个有序链表(递归和迭代)

1.题目

将两个有序的链表list1和list2合并为一个链表,比如list1为 1->3->4, list2为 1->2->6, 合并成的新链表结果应该为 1->1->2->3->4->6

2.思路

思路01:【迭代解法】可以采用暴力破解,递归的方式,一次比较两个链表中节点中哪个值更小,就放到新链表中,不断遍历两个链表,直到其中一个链表为null之后,直接把两外一个链表的剩余部分放到新的要合并的链表中,即完成了链表合并操作,为了过多边界条件判断,采用通用的设置哑节点 dummy的方式作为新链表的虚拟前置节点,最后返回的是 dummy.next即可。新链表中用 prev = dummy,然后作为临时节点,不断更新和移动即可

思路02:【递归解法】上述问题实际上,可以改为 listNew.next = merge(list1.next, list2);「假设 list1的头结点比list2的头结点值小的情况下」,和总问题的出入参一样,就可以采用递归的解法

3.代码实现

        3.1)【迭代解法】


public static ListNode merge(ListNode node1, ListNode node2){
    ListNode dummy = new ListNode(0);
    ListNode prev = dummy;
    while(list1 != null && list2 != null){
        if(list1.val <= list2.val){
            prev.next = list1;
            list1.next = list1;
        }else{
            prev.next = list2;
            list2.next = list2;
        }

        prev.next = prev;
    }

    prev.next = list1 != null ? list1 : list2;

    return dummy.next;
}

       3.2)【递归解法】

public static ListNode mergeList(ListNode list1, ListNode list2){
    if(list1 == null){
        return list2;
    }
    
    if(list2 == null){
        return list2;
    }

    // 以头结点更新的链表为基础的链表,另外一个链表向她上边合并
    if(list1.val <= list2.val){
        list1.next = mergeList(list1.next, list2);
        return list1;
    }else if(list1.val > list2.val){
        list2.next = mergeList(list2.next, list1);
        return list2;
    }

}

4.其他思考和分析

       4.1)时间复杂度和空间复杂度的分析

          讲解了 迭代和递归两种解法,代码实例是Java ,从中直观看到了 迭代和递归的时间复杂度都是 O(m+n),但是迭代的空间复杂度只有O(1),而递归的空间复杂度到了O(m+n),如果两个链表非常长的情况下,可能会引起栈的溢出。
 

       4.2)相关疑问和解答

                [疑问 01]: 在递归解法中,定义的dummy和prevHead,两者究竟是什么关系? 它俩的内存地址一样吗? 为什么移动prev时,dummy没有跟着移动,但是结果赋值时,dummy同步变化了呢? 

                答:请看下图

 

       4.3)参考链接和资料等

381,合并两个有序链表(易)

leetcode-21 合并两个有序链表

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值