【递归】2. 合并两个有序链表

leetcode链接:https://leetcode.cn/problems/merge-two-sorted-lists/description/

在这里插入图片描述
浅浅带过一下使用非递归的方式:

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        //1.创建头节点
        ListNode *newHead = new ListNode(0);
        //2.创建用于迭代的结点
        ListNode *prev = newHead;

        while(list1 != nullptr && list2 != nullptr)
        {
            if (list1->val < list2->val)
            {
                prev->next = list1;
                list1 = list1->next;
            }
            else
            {
                prev->next = list2;
                list2 = list2->next;
            }

            //prev结点迭代
            prev = prev->next;
        }

        //处理没有被链入的结点
        prev->next = list1 == nullptr ? list2 : list1;

        //释放头节点
        prev = newHead->next;
        delete newHead;
        return prev;
    }
};

使用递归

使用递归必须要思考下面三个问题:

1.找到重复的子问题  
2.具体某一个子问题在做什么事情
3.找到递归的出口

1.找到重复的子问题

在这里插入图片描述

子问题:将L1和L2中较小的一个作为头节点,合并剩下的链表

函数头:

 dfs(list1, list2);

2.具体某一个子问题在做什么事情

第一步:比较节点的大小
第二步:将小的节点的next链接到下一个小的节点的前面

l1->next = dfs(l1->next, l2);
或者
l2->next = dfs(l2->next, l1);

3.防止死递归

l1为空或者l2为空的时候,退出

代码:

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        return dfs(list1, list2);
    }

    ListNode* dfs(ListNode* list1, ListNode* list2)
    {
        //1.找到递归的出口
        if (list1 == nullptr)
            return list2;

        if (list2 == nullptr)
            return list1;
        
        //2.1 找到小的那个节点
        if (list1->val < list2->val)
        {
            //2.2合并链表
            list1->next = dfs(list1->next, list2);
            //2.3返回头节点
            return list1;
        } 
        else
        {
            list2->next = dfs(list2->next, list1);
            return list2;
        }

    }
};

总结:

循环 vs 递归
循环:处理重复的子问题
递归:有重复的子问题,进行处理

因此,循环和递归可以互相转化

什么时候用循环?什么时候用递归?
使用递归的问题,如果想改成循环,需要借助栈。而如果借助栈,使用循环,就会很麻烦!
什么样的情况适用递归?递归调用类似下面这种情况
在这里插入图片描述
什么样的情况适用循环?递归调用类似下面这种情况
在这里插入图片描述
只有一个分支,递归改成循环就很简单。
举例:遍历数组

递归 vs 深搜
递归的展开头图,其实就是对一棵树做一次深度优先遍历(dfs)
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值