【算法】递归

server/2024/9/25 8:38:21/

【ps】本篇有 5 道 leetcode OJ。 

目录

一、算法简介

二、相关例题

1)汉诺塔问题

.1- 题目解析

.2- 代码编写

2)合并两个有序链表

.1- 题目解析

.2- 代码编写

3)反转链表

.1- 题目解析

.2- 代码编写

4)两两交换链表中的节点

.1- 题目解析

.2- 代码编写

5)Pow(x, n)

.1- 题目解析

.2- 代码编写


一、算法简介

        常见的、典型的搜索算法有 BFS(宽度优先搜索)和 DFS(深度优先搜索)。

        而递归是搜索算法的基础。如果将递归看作是一个大类,那么搜索算法就是递归下面的一个分支,因此要掌握搜索算法,就必须掌握递归

【Tips】递归是什么?

        简单来说,递归就是一个函数自己调用自己的行为。


【Tips】为什么会用到递归

        把一个问题看作是主要问题,这个主要问题可以划分为若干个相同的子问题,递归就主要针对这种场景。


【Tips】如何理解递归

  1. 递归展开的细节图(本质是对一棵树进行DFS);
  2. 借助二叉树的相关题目;
  3. 宏观看待递归的过程:不要在意递归展开的细节图!把递归的函数当成是一个黑盒,相信这个黑盒一定能完成任务!

【Tips】如何写好递归

  1. 函数头的设计:先找到相同的子问题!
  2. 函数体的书写:只关心某一个问题是如何解决的!
  3. 递归函数的出口:问题不能再细分的临界条件!

二、相关例题

1)汉诺塔问题

面试题 08.06. 汉诺塔问题

.1- 题目解析

        假设 n = 1,只有一个盘子,很简单,直接把它从 A 中拿出来,移到 C 上。

        如果 n = 2 ,就要借助 B 了,因为小盘子必须时刻都在大盘子上面,共需要 3 步。

        如果 n > 2 呢?思路和上面是一样的,我们可以把 n 个盘子看成两个部分,一部分有 1 个盘子,另一部分有 n - 1 个盘子,于是就将最初的 n 个盘子从 A 移到 C 的问题,转化成了将 n - 1 个盘子从 A 移到 C 的问题, 依次类推,直至转化成 1 个盘子的问题时,问题也就解决了。

        如果原问题可以分解成若干个与原问题结构相同但规模较小的子问题,往往可以用递归的方法解决:

  1.  n = 1 时,直接把盘子从 A 移到 C;
  2.  n > 1 时,先把上面 n - 1 个盘子从 A 移到 B(子问题,递归);再将最大的盘子从 A 移到 C;最后将 B 上 n - 1 个盘子从 B 移到 C(子问题,递归)。

.2- 代码编写

class Solution {
public:void hanota(vector<int>& A, vector<int>& B, vector<int>& C) {dfs(A,B,C,A.size());//参数说明:待转移的盘子、中转位置的盘子、目的位置的盘子、转移的盘子个数}//1.函数头void dfs(vector<int>& A, vector<int>& B, vector<int>& C,int n){//3.递归出口if(n==1){C.push_back(A.back());A.pop_back();return;}//2.函数体dfs(A,C,B,n-1);C.push_back(A.back());A.pop_back();dfs(B,A,C,n-1);}
};

2)合并两个有序链表

21. 合并两个有序链表

.1- 题目解析

.2- 代码编写

/*** 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) {return dfs(list1,list2);}ListNode* dfs(ListNode* l1,ListNode* l2){if(l1==nullptr) return l2;if(l2==nullptr) return l1;if(l1==nullptr && l2==nullptr) return nullptr;if(l1->val<=l2->val){l1->next=dfs(l1->next,l2);return l1;}else{l2->next=dfs(l1,l2->next);return l2;}}
};

3)反转链表

206. 反转链表

.1- 题目解析

.2- 代码编写

/*** 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* newhead=reverseList(head->next);head->next->next=head;head->next=nullptr;return newhead;}
};

4)两两交换链表中的节点

24. 两两交换链表中的节点

.1- 题目解析

        两两为一组进行逆置。

.2- 代码编写

/*** 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;ListNode* ret=head->next;ListNode* tmp=swapPairs(ret->next);ret->next=head;head->next=tmp;return ret;}
};

5)Pow(x, n)

50. Pow(x, n)

.1- 题目解析

        本题涉及快速幂算法,用递归实现快速幂即可。

.2- 代码编写

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;}
};


http://www.ppmy.cn/server/121732.html

相关文章

JVM的基本组成

一、JDK\JRE\JVM JDK: 全称 "Java Development Kit" &#xff0c;Java 开发工具包&#xff0c;提供 javac 编译器、jheap、jconsole 等监控工具;JRE: 全称"Java Runtime Environment"&#xff0c;Java 运行环境&#xff0c;提供Class Library 核心类库 JV…

Android 保存本地图片

1.工具类BitmapUtils public class BitmapUtils {public static Bitmap mirror(Bitmap rawBitmap) {Matrix matrix new Matrix();matrix.postScale(-1f, 1f);return Bitmap.createBitmap(rawBitmap, 0, 0, rawBitmap.getWidth(), rawBitmap.getHeight(), matrix, true);}publ…

设计原则模式概览

前言 架构设计是软件系统稳定的核心因素&#xff0c;也是程序员晋级架构师的核心因素&#xff0c;建议日常开发过程中针对设计进行深挖与思考 核心 分清楚哪些是稳定的&#xff0c;哪些是变化的&#xff08;一定有稳定跟变化的成分&#xff09;&#xff1b; 捋清楚哪些是类设计…

智能听诊器宠物社区的新宠

在宠物社区中&#xff0c;智能听诊器正迅速成为宠物主人的新宠。这款设备通过高精度传感器和智能算法&#xff0c;为宠物提供实时的健康监测和诊断建议。智能听诊器的移动健康应用&#xff0c;使得宠物主人能够随时随地访问宠物的健康数据&#xff0c;并与兽医进行交流。 智能…

python学习-11【图形用户界面】

1、EasyGUI 快速入门 在命令提示符中使用 pip install easygui 命令下载并安装 Easy GUI 功能演示 1、 msgbox() 函数可以显示一个对话框&#xff0c;默认提供名为 OK 的按钮 msgbox(msg(message), title, ok_buttonOK, imageNone, rootNone) 2、ccbox() 函数用于提供选择功能…

Cilium + ebpf 系列文章- XDP (eXpress data Path)(四)

前言: 现有网络容器的性能消耗与通信简单流程: 1、只要是Pod都有自己的网络命名空间。 2、Pod的网络命名空间由Pod内的容器使用并共享但是由暂停容器(Pause Container)管理。 3、Pod内的容器网络通过veth_pair对与主机网络命名空间打通。 …

短视频矩阵管理系统贴牌 源码开发

抖音账号矩阵的开发核心维度包括&#xff1a; 多账号管理开发维度&#xff1a;通过运用不同类型的账号矩阵&#xff0c;可以实现统一且便捷的管理。目前&#xff0c;矩阵系统支持管理抖音、快手、视频号,b站的账号&#xff0c;未来计划加入小红书,tk等等的账号管理。 矩阵账号…

蓝队技能-应急响应篇Web内存马查杀JVM分析Class提取诊断反编译日志定性

知识点&#xff1a; 1、应急响应-Web内存马-定性&排查 2、应急响应-Web内存马-分析&日志 注&#xff1a;传统WEB类型的内存马只要网站重启后就清除了。 演示案例-蓝队技能-JAVA Web内存马-JVM分析&日志URL&内存查杀 0、环境搭建 参考地址&#xff1a;http…