递归算法:代码迷宫中的无限探索

✨✨✨学习的道路很枯燥,希望我们能并肩走下来!

目录

前言

一 深入理解递归

二 迭代VS递归

三 递归算法题目解析

3.1 汉诺塔问题

 3.2 合并两个有序链表

3.3 反转链表 

3.4 两两交换链表中的节点 

3.5 Pow(x,n)(快速幂) 

​四 总结

总结


前言

作为递归、搜索与回溯算法系列的第一篇,本篇详细介绍了递归算法的使用,让使用者了解递归运算,而不是仅仅停留在表面, 文章可能出现错误,如有请在评论区指正,让我们一起交流,共同进步!


一 深入理解递归

二 迭代VS递归

三 递归算法题目解析

3.1 汉诺塔问题

面试题 08.06. 汉诺塔问题 - 力扣(LeetCode)

 

我们简单取1到4个圆盘进行移动,我们从宏观角度发现这是一个重复子问题

class Solution {
public:
    void move(vector<int>& A, vector<int>& B, vector<int>& C,int n)
    {
        if(n == 1)
        {
            C.push_back(A.back());
            A.pop_back();
            return;
        }
        move(A,C,B,n-1);
        C.push_back(A.back());
        A.pop_back();
        move(B,A,C,n-1);
    }


    void hanota(vector<int>& A, vector<int>& B, vector<int>& C) {
        int n = A.size();
        move(A,B,C,n);
    }
};

 如果我们在笔试中遇到的,只需要保证能通过就行

不讲武德版:

class Solution {
public:
    void hanota(vector<int>& A, vector<int>& B, vector<int>& C) {
        C = A;
    }
};

 3.2 合并两个有序链表

21. 合并两个有序链表 - 力扣(LeetCode)

 我们之前是使用迭代(循环)来做的

迭代:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
typedef struct ListNode ListNode;
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) 
{
    ListNode* l1 = list1;
    ListNode* l2 = list2;
    ListNode* newHead = NULL;
    ListNode* newTail = NULL;
    newHead = newTail = (ListNode*)malloc(sizeof(ListNode));
    if(l1==NULL)
    {
        return l2;
    }
    if(l2==NULL)
    {
        return l1;
    }
    while(l1&&l2)
    {
        if(l1->val<l2->val)
        {
            newTail->next=l1;
            newTail=newTail->next;
            l1=l1->next;
        }
        else
        {
            newTail->next=l2;
            newTail=newTail->next;
            l2=l2->next;
        }
    }
    if(l1)
    {
        newTail->next=l1;
    }
    else
    {
        newTail->next=l2;
    }
    ListNode* ret = newHead->next;
    free(newHead);
    return ret;
}

递归:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        if(list1 == nullptr)    return list2;
        if(list2 == nullptr)    return list1;

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

    }
};

3.3 反转链表 

206. 反转链表 - 力扣(LeetCode)

 

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(head == nullptr ||head->next == nullptr) return head;
        ListNode* newNode = reverseList(head->next);
        head->next->next = head;
        head->next = nullptr;
        return newNode;
    }
};

3.4 两两交换链表中的节点 

24. 两两交换链表中的节点 - 力扣(LeetCode)

 

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        if(head == nullptr || head->next == nullptr)    return head;
        auto newNode = swapPairs(head->next->next);
        auto ret = head->next;
        head->next->next = head;
        head->next = newNode;
        return ret;
    }
};

3.5 Pow(x,n)(快速幂) 

50. Pow(x, n) - 力扣(LeetCode)

 

class Solution {
public:
    double myPow(double x, int n) {
        return n<0 ? 1.0/Pow(x,-(long long)n) : Pow(x,n);
    }

    double Pow(double x, long long n) {
        if(n == 0)  return 1.0;
        double tmp = Pow(x,n/2);
        return n%2 == 0 ? tmp*tmp : tmp*tmp*x;
    }
};

 用long long避免int无法存n为2的-31次方

 四 总结

        1.  从题目发掘出重复的子问题

        2.  只针对某一子问题考虑解决方法

        3. 注意递归出口


总结

✨✨✨各位读友,本篇分享到内容是否更好的让你理解递归算法,如果对你有帮助给个👍赞鼓励一下吧!!
🎉🎉🎉世上没有绝望的处境,只有对处境绝望的人。
感谢每一位一起走到这的伙伴,我们可以一起交流进步!!!一起加油吧!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/726732.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CRMEB-PHP多商户版安装系统配置清单

系统在安装完成之后&#xff0c;需要对系统进行一系列的配置&#xff0c;才能正常使用全部的功能&#xff0c;以下是官方整理的配置清单 平台后台 商户后台

计算机SCI期刊,中科院3区,易过审,专业认可度不错

一、期刊名称 Journal of Cloud Computing-Advances Systems and Applications 二、期刊简介概况 期刊类型&#xff1a;SCI 学科领域&#xff1a;计算机科学 影响因子&#xff1a;4 中科院分区&#xff1a;3区 三、期刊征稿范围 Journal of Cloud Computing&#xff1a;A…

MyBatis 动态 SQL怎么使用?

引言&#xff1a;在现代的软件开发中&#xff0c;数据库操作是任何应用程序的核心部分之一。而在 Java 开发领域&#xff0c;MyBatis 作为一款优秀的持久层框架&#xff0c;以其简洁的配置和强大的灵活性被广泛应用。动态 SQL 允许开发人员根据不同的条件和场景动态地生成和执行…

Flutter 简化线程Isolate的使用

文章目录 前言一、完整代码二、使用示例1、通过lambda启动线程2、获取线程返回值3、线程通信4、结束isolate 总结 前言 flutter的线程是数据独立的&#xff0c;每个线程一般通过sendport来传输数据&#xff0c;这样使得线程调用没那么方便&#xff0c;本文将提供一种支持lambd…

CIRCOS圈图绘制 - circos安装

Circos是绘制圈图的神器&#xff0c;在http://circos.ca/images/页面有很多CIRCOS可视化的示例。 Circos可以在线使用&#xff0c;在线使用时是把表格转为圈图&#xff0c;不过只允许最大75行和75列&#xff1b;做一些简单的示意图会比较好&#xff0c;最后时会介绍下在线的tab…

vue大屏适配方案

前言 开发过大屏的铁汁们应该知道&#xff0c;前期最头疼的就是大屏适配&#xff0c;由于大屏项目需要在市面上不是很常见的显示器上进行展示&#xff0c;所以要根据不同的尺寸进行适配&#xff0c;今天我将为大家分享的我使用的大屏适配方案&#xff0c;话不多说&#xff0c;直…

MySQL Server和Server启动程序(一)

MySQL Server mysqld&#xff0c;也称为MySQL Server&#xff0c;是一个单线程多任务的程序&#xff0c;它在MySQL安装中执行大部分工作。它不会生成额外的进程。MySQL Server管理对包含数据库和表的MySQL数据目录的访问。数据目录也是其他信息&#xff08;如日志文件和状态文…

Windows Server配置iSCSI,做ESXI共享存储

1&#xff1a;使用一台Windows Server2022主机配置iSCSI&#xff0c;准备给ESXI8.0做共享存储使用。有一些ESXI的功能必须使用共享存储才行&#xff0c;比如HA的功能。 2&#xff1a;登录系统&#xff0c;点击添加角色和功能。 3&#xff1a;之后一路下一步&#xff0c;在选择…

健身器械行业外贸ERP管理降本增效解决方案

随着经济的迅速发展&#xff0c;以及健身锻炼的普及&#xff0c;人们对健身器材的需求量也在大幅度增加。欧美市场增长迅猛&#xff0c;家用健身器材热度飙升&#xff0c;尤其是跑步机、健身单车等轻便型家用健身器材&#xff0c;备受消费者青睐。 出口的主要国家包括&#xf…

Git 和 TortoiseGit 安装和配置(图文详解)

使用git&#xff0c;需要在Windows上需要安装两个软件&#xff1a;1&#xff09;Git 2&#xff09;TortoiseGit 若需要&#xff0c;可以下载TortoiseGit汉化语言包。 注意&#xff1a;tortoiseGit是在安装了Git的基础上运行的&#xff0c;所以需要先安装Git&#xff0c;后安装…

智慧校园导航系统:技术驱动下的校园管理与师生体验革新

随着智慧校园建设的不断推进&#xff0c;校园导航系统作为提升校园管理效率、优化师生出行体验的重要工具&#xff0c;正逐渐成为各大高校的标配。本文将重点介绍维小帮智慧校园导航系统&#xff0c;如何通过创新的设计和功能&#xff0c;解决校园导航中的种种难题&#xff0c;…

1分钟带你部署本地Llama3大模型

介绍 LLaMa 3由Meta于2024年4月18日正式发布&#xff0c;这一版本是对先前LLaMa系列的重大升级。新发布的模型包括8B&#xff08;80亿参数&#xff09;和70B&#xff08;700亿参数&#xff09;两个版本&#xff0c;这两个版本在一系列行业标准基准测试中展示了最先进的性能。 从…

低版本火狐浏览器报错:class is a reserved identifier

低版本火狐浏览器报错&#xff1a;class is a reserved identifier 原因&#xff1a;react-dnd&#xff0c;dnd-core 等node包的相关依赖有过更新&#xff0c;使得在低版本火狐浏览器中不支持 class 解决方法&#xff1a;在使用webpack打包构建时&#xff0c;编译排除node_modu…

7,KQM模块的驱动

1&#xff0c;查资料&#xff0c;查模块的通信接口&#xff08;单片机和模块之间采用什么方式通信&#xff09;硬件接口&#xff0c;驱动方式(串口驱动用串口发送接收PC10&#xff0c;PC11) 只用了三个脚&#xff1a;VCC &#xff27;&#xff2e;&#xff24; &#xff34;&…

pdf只要前几页,pdf怎么只要前几页

在现代办公和学习环境中&#xff0c;PDF文件已成为我们日常处理信息的重要工具。然而&#xff0c;有时我们并不需要整个PDF文件的内容&#xff0c;而只是其中的几页。那么&#xff0c;如何高效地提取PDF文件中的特定页面呢&#xff1f;本文将为您介绍几种实用的方法。 打开 “ …

Python在Word文档中插入图片,设置文字环绕

在Word文档中插入图片能够提供更直观的信息&#xff0c;使文档变得更加生动和具有吸引力&#xff0c;从而增强阅读体验。插入图片时&#xff0c;我们还可以调整图片大小&#xff0c;以及设置合适的文字环绕方式&#xff0c;确保文字和图片之间的排版不会混乱&#xff0c;达到最…

SVN学习(002 svn冲突解决)

尚硅谷SVN高级教程(svn操作详解) 总时长 4:53:00 共72P 此文章包含第20p-第p29的内容 冲突 产生冲突的操作 &#xff08;第一种 相互不影响的操作&#xff09; 用户1修改第二行 用户2修改第四行 用户1提交 用户2提交&#xff0c;提交的时候会提示版本已过时 这时将用…

树莓派4B学习笔记11:PC端网线SSH连接树莓派_网线连接请求超时问题解决

今日继续学习树莓派4B 4G&#xff1a;&#xff08;Raspberry Pi&#xff0c;简称RPi或RasPi&#xff09; 本人所用树莓派4B 装载的系统与版本如下: 版本可用命令 (lsb_release -a) 查询: Opencv 版本是4.5.1&#xff1a; 今日学习使用网线连接树莓派&#xff0c;网线可以提供更…

STM32学习笔记(六)--引脚重映射详解

STM32F103C8T6引脚定义&#xff1a; 在STM32微控制器中&#xff0c;外设引脚的复用功能&#xff08;Alternate Function&#xff0c;AF&#xff09;有时会出现冲突&#xff0c;例如当USART2_CTS和TIM2_CH1同时需要使用相同的引脚时。此时&#xff0c;可以通过引脚重映射功能&am…

【方法】如何在ZIP文件中添加或删除文件?

ZIP文件是我们在日常工作中常用的压缩格式。有时候&#xff0c;我们需要在已有的ZIP文件中添加或删除文件。下面来看看具体如何操作。 首先&#xff0c;我们要确保安装了ZIP文件管理软件&#xff0c;如WinRAR、7-Zip或Windows自带的文件资源管理器。 添加文件&#xff1a; 使…