递归+迭代实现合并两个有序链表

合并两个有序链表-递归及迭代实现

题目链接:合并两个有序链表

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的 – 告诉我们不能重新new节点。

img

示例1:

输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]

示例2:

输入:l1 = [], l2 = []
输出:[]

1.递归实现

STEP1:重复子问题,及递归函数头的设计

由于两个链表都是升序的,所以我们让list1list2去比较,让其val较小的那个作为头结点;转化为子问题:在新的两条链表中,继续去找新的头结点…

STEP2:只关心当前子问题做的事情

当前子问题做了什么,它将当前的头结点链接到下一个子问题返回的头结点上,我们相信子问题一定能返回正确的头结点。

STEP3:递归终止条件

list1list2有一个为空就返回。

最终代码实现如下:

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        if(list1 == nullptr) return list2;
        if(list2 == nullptr) return list1;

        ListNode* head = list1;
        if(list1->val <= list2->val)
        {
            head->next = mergeTwoLists(list1->next, list2);
        }
        else
        {
            head = list2;
            head->next = mergeTwoLists(list1, list2->next);
        }
        return head;
    }
};

时间复杂度: O(n + m),n 和 m 分别为两个链表的长度。每一次递归都会去掉一个list1 或者list2头节点,因此时间复杂度取决于两链表加起来的长度。

空间复杂度: O(n + m)。递归调用函数会消耗栈空间,消耗栈空间的大小和递归调用函数的深度有关,当递归调用结束时,mergeTwoLists函数最多被调用 m + n 次。

2.迭代实现

首先定义一个哨兵位的头结点prehead,这样能方便后序的插入,我们直接将较小的节点插入到哨兵位头结点即可,等待节点链接完毕,返回prehead->next

在这里插入图片描述

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        if(list1 == nullptr) return list2;
        if(list2 == nullptr) return list1;

        ListNode* prehead = nullptr, *tail = nullptr;
        prehead = new ListNode(-1);
        tail = prehead;
        while(list1 && list2)
        {
            if(list1->val <= list2->val)// list1的节点小, 尾差到tail后面
            {
                tail->next = list1;// tail链接下一个节点
                list1 = list1->next; 
                tail = tail->next;// tail继续走到新链表的后面, 准备链接其他节点
            }
            else// list2的节点小, 尾差到tail后面
            {
                tail->next = list2;
                list2 = list2->next;
                tail = tail->next;
            }
        }
        // 判断一下, 防止遗漏节点
        if(list1) tail->next = list1;
        else tail->next = list2;

        ListNode* ret = prehead->next;
        delete prehead;
        return ret;
    }
};

时间复杂度: O(n + m),n 和 m 分别为两个链表的长度。循环就是在遍历两条链表,所以时间复杂度就是两条链表的和。

空间复杂度: O(1)。只开辟了哨兵为头结点和其他若干个变量的空间。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值