leetcode之递归详解

【LeetCode】递归精选8题——基础递归、链表递归 LeetCode 递归精选8题(包含基础递归、链表递归) 详解 阅读详情

递归

其实递归和二叉树遍历很像,要理解递归,就要理解二叉树遍历.

可以看看这个理解一下

首先说明一个问题,简单阐述一下递归,分治算法,动态规划,贪心算法这几个东西的区别和联系,心里有个印象就好。

递归这种尽量能不用就不用,有时候会造成过大的额外开销以及栈溢出,可以根据这个思想选用贪心算法,动态规划,bfs,dfs等

递归是一种编程技巧,一种解决问题的思维方式;分治算法和动态规划很大程度上是递归思想基础上的(虽然动态规划的最终版本大都不是递归了,但解题思想离不开递归),解决更具体问题的两类算法思想;贪心算法是动态规划算法的一个子集,可以更高效解决一部分更特殊的问题。以最经典的归并排序为例,它把待排序数组不断二分为规模更小的子问题处理,这就是 “分而治之” 这个词的由来。显然,排序问题分解出的子问题是不重复的,如果有的问题分解后的子问题有重复的(重叠子问题性质),那么就交给动态规划算法去解决!

使用递归的关键是要明白:递归函数的作用是什么,从宏观的角度去理解递归,不用太在意递归是如何进行调用的。
如果想具体的进一步了解,可以使用小的数据量进行手动的推导,深度的理解递归中的具体调用。

递归有两个重要的组成部分:

递归终止条件: 用来跳出递归,写好递归先从简单的入手,弄清楚最简单的情况,就可以写出终止条件
具体实现:实现递归函数的功能

明白一个函数的作用并相信它能完成这个任务,千万不要试图跳进细节

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点。

    3
   / \
  9  20
    /  \
   15   7
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int recall(TreeNode* root,int depth)
    {
        if(root==NULL)
        return depth;
        int a=recall(root->left,depth+1);//左边子树的最大深度
        int b=recall(root->right,depth+1);//右边子树的最大深度
        return max(a,b);
    }
    int maxDepth(TreeNode* root) {
        int depth=0;//这里为什么初始值是0呢?
        return recall(root,depth);//确定这个函数的作用就是给定root返回左右子树的最大深度;
        
    }
};
/* 为什么初始值为0 因为为NULL的终止条件相当于加了1正好是root第一层 */


递归递归先递后归

比如阶乘

f(6)=> 6 * f(5)=> 6 * (5 * f(4))=> 6 * (5 * (4 * f(3)))=> 6 * (5 * (4 * (3 * f(2))))=> 6 * (5 * (4 * (3 * (2 * f(1)))))=> 6 * (5 * (4 * (3 * (2 * 1))))=> 6 * (5 * (4 * (3 * 2)))=> 6 * (5 * (4 * 6))=> 6 * (5 * 24)=> 6 * 120=> 720

img

先进去然后再逐层返回

重点来了

递归的套路

套路一:不要纠结递归的整个过程。

既然递归是一个反复调用自身的过程,这就说明它每一级的功能都是一样的,因此我们只需要关注一级递归的解决过程即可。

套路二:这个主函数是做什么的。

套路三:找到整个递归的终止条件,也就是说终止条件是什么,在满足终止条件情况下里面又做了什么。

套路四:找返回值:应该给上一级返回什么信息。

套路五:我们精简后的一级递归是用来做什么的。

总之就是:这个问题怎么分成子问题,这个函数干了什么,进去前干啥,出来后干啥,以及我要返回上一层内容是啥;
相信各位可以发现这个和动态规划很像,有[备忘录]的递归效率就差不多和动态规划一样;不一样的思路.动态规划的自底向上.

(1)判断是否有最优子结构(没有就转化)

(2)确定状态变量

(3)确定dp数组含义以及大小

(4)选择择优,数学归纳找出转移方程

(4)找到base case

(5)选择遍历dp方向

(6)看看能不能优化,也就是状态压缩

可以看出,递归是由目标点一直到终止条件再逐层返回,而动态规划是由终止条件一直迭代到目标点

eg.

给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。

说明: 叶子节点是指没有子节点的节点。

给定如下二叉树,以及目标和 sum = 22,

          5
         / \
        4   8
       /   / \
      11  13  4
     /  \      \
    7    2      1

思路: 函数:给定节点,判定是否达到目标

终止条件:子节点,判定是否符合结果

下一层是一左一右节点有没有满足;返回上一层的结果只要有一个为true就可以;

所以列出函数

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool a(TreeNode* root,int target,int sum)
    {
         if(root==NULL) return false;
        target+=root->val;
        if(root->left==NULL&&root->right==NULL&&target==sum) return true;
        if(root->left==NULL&&root->right==NULL&&target!=sum) return false;
       
        cout<<target;
        // if(target==sum) return true;
       return a(root->left,target,sum)||a(root->right,target,sum);

    }
    bool hasPathSum(TreeNode* root, int sum) {
        if(root==NULL)
        return false;
        int target=0;
        return a(root,target,sum);
        
    }
};

定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

这个题目有点意思,因为每一层返回的都是一样的东西,终止条件赋予了返回值

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:

    ListNode* reverseList(ListNode* head) {
        {
         //最后都是返回头指针
         if(head==NULL||head->next==NULL)
        {
            return head;//这里就是给定了头指针

        }
        ListNode* res=reverseList(head->next);//函数的左右每一层都把后面节点的next指向自己,然后自己指向next
        head->next->next=head;
        head->next=NULL;
        return res;//每一层都要返回的是结果的头指针;

        }
    }
    };

图解

在这里插入图片描述

【算法系列】递归与分治详解(附LeetCode例题) 一、递归与分治1 1、算法思想 对k个子问题分别求解,如果子问题的规模仍然不够小,则再划分为k个子问题。 如此递归地进行下去,直到问题规模足够小,很容易求出其解为止。 将求出的小规模问题的解合并成一个更大规模的问题的解,自底向上逐步求出原来问题的解。 分治法的设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。 2、递归的概念 直接或者间接地调用自... 阅读详情

相关推荐

IEC103协议实战指南:报文解析与传输优化策略

本文深入解析IEC103协议在电力自动化系统中的核心应用,重点拆解其固定帧与可变帧两种报文格式,并详细阐述了主从问答与非平衡传输机制。文章结合实战经验,针对报文解析中的常见问题(如字节序、超时重发)提供了解决方案,并探讨了传输层优化策略,旨在帮助工程师实现更可靠、高效的通信链路。

r2s3t4的博客 541

LeetCode 刷题 -- 递归

在上述代码的递归调用里,调用的是f(n-1)和f(n-2),但是在f(n-1)的递归里面,f(n-2)其实已经计算过了,但是后面还会重复计算。如果最后一步走1个台阶,那么就是n=n-1时候的方法,如果最后一步走2个台阶,那么就是n=n-2的方法,因此 f(n)=f(n-1)+f(n-2)3、如果只有一个节点为null,这种是需要调换左右节点的,假设左节点不为null,右节点为null,那么调换之后,左节点为null,右节点不为null,因此可以不需要特殊处理。)同时,这个节点的子节点也要进行相同的操作。

qq_43325216的博客 1385

Claude Desktop Cowork国内实操指南:本地文件自动化办公

大语言模型正从‘问答式AI’迈向‘执行型协作者’,其核心能力在于直接操作本地文件、调用系统工具并嵌入真实工作流。Claude Desktop的Cowork模式正是这一范式的代表,它通过轻量沙箱VM实现对Excel、PPT、PDF、音视频等办公资产的读写与处理,无需手动编码即可完成数据清洗、会议纪要生成、自动化报告输出等任务。技术价值体现在权限可控、环境隔离、结果可交付;典型场景覆盖行政文秘的文档流转、销售运营的数据分析、开发者的脚本调试与环境验证。本文聚焦国内用户高频卡点——网络链路、系统权限与工作流断层,

weixin_30617737的博客 468

leetcode - 递归

目录 98.验证搜索二叉树 22.括号生成 100.相同的树 101.对称二叉树 104.树的最大深度 108.将有序数组转换成搜索二叉树 110.平衡二叉树 111.二叉树的最小深度 112.路径总和 226.翻转二叉树 98.验证搜索二叉树 给定一个二叉树,判断其是否是一个有效的二叉搜索树。 假设一个二叉搜索树具有如下特征: 节点的左子树只包含小于当前节点的数。 ...

mike_jun的博客 834

【立创开源】太阳能板充电方案单节3.7v锂电池充电

一直对太阳能板感兴趣,老是感觉充电好麻烦,要是放在那里就可以自己充电多好,所以尝试做了一个太阳能充电板。因为这几天都是阴天,所以测试效果不太好,但是下雨天也是能充电的,但是基本只能维持电量不掉,电压差不多4.2v以上,电流只有2mA。中午出太阳的时候,隔着玻璃放在太阳下测试,电流有12mA以上。能充起一点点电。等大晴天看一看能不能达到卖家说50mA。┗( T﹏T )┛感觉达不到。这个东西只能当一个玩具(;′⌒`)。不过如果汽车上一些行车记录仪加一个这个,汽车经常在太阳下停车,可能再也不用充电了。

贾saisai的博客 1万+

BLDC方波控制双闭环Simulink仿真模型

无刷直流电机方波控制双闭环Simulink仿真模型搭建详细教程,包括速度PI环、电流PI环、换向逻辑和受控电压源,仿真结果良好。

m0_57458432的博客 6870

leetcode刷题---递归思想

如果在函数中存在着调用函数本身的情况,这种现象就叫递归。递归的思想就是,将大问题分解为小问题来求解,然后再将小问题分解为更小的问题。这样一层层地分解,直到问题规模被分解得足够小,不用继续分解,可以直接计算结果为止。如果把这个一层层分解的过程画成图,它其实就是一颗树,叫做递归树。if n

weixin_40734030的博客 929

避开这些坑!晶圆封装中Wire Bonding(引线键合)的5种常见不良与实战调试心得

本文深入探讨晶圆封装中Wire Bonding(引线键合)的5种常见不良现象,包括Wire Offset、BSOB不良、球径/球厚异常、弧度不良和IMC问题。通过实际案例和参数优化方案,帮助工程师提升封装质量和可靠性,特别适用于半导体封装领域的专业人士。

weixin_33672109的博客 525

Leetcode算法基础篇-递归算法

递归(Recursion):指的是一种通过重复的方法。在绝大数编程语言中,可以通过在函数中再次调用函数自身的方式来实现递归。

deardeer的博客 981

筹码峰五句口诀,看懂主力的秘密动作!(附实战图示)

筹码图的价值在于,它不像K线那样容易造假。主力可以骗线,但骗不了筹码分布。主力在不在;是吸筹还是出货;接下来是变盘还是震荡。这五句口诀可以说是“筹码阅读的入门圣经”:单峰坚挺变盘在即,双峰对垒高抛低吸;上峰不移主力在跑,多峰林立行情不止;下峰不移不离不弃,筹码识庄稳中取利!📌市场从来不是靠猜,而是靠看清。筹码,就是主力最真实的痕迹。如果你想学会提前布局、跟庄不被甩,学会看筹码峰——这一步必须打牢!

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 1164

120、ISP 驱动架构解析:从 V4L2 请求到 ISP 硬件的配置下发流程

本文以实际案例解析ISP驱动架构的V4L2到硬件配置下发流程。作者通过一个因内存共享导致画面闪烁的bug案例,详细剖析了用户空间参数通过V4L2结构体传递、驱动层拆包与硬件寄存器映射、时序同步机制等关键环节。特别强调深拷贝、dirty flag增量更新、shadow register等实现要点,并给出多路并发隔离、寄存器写入失败等典型问题的排查方法。文章建议开发者深入理解参数到寄存器的转换过程,推荐通过debugfs实时监控寄存器状态,避免过度依赖自动调试工具。全文以实践为导向,对ISP驱动开发具有直接指导

sundong_81的博客 159

递归究竟是什么?如何快速编写正确的递归代码? —— 力扣经典面试题详解

归是一种算法设计技术,它允许一个函数在其定义或说明中有直接或间接调用自身的方法。递归在数学和计算机科学中有着广泛的应用,它通过将复杂问题分解为规模较小、形式相同的子问题来求解。递归的基本原理包括:每一级的函数调用都有自己的变量;每一次函数调用都会有一次返回;递归函数中,位于递归调用前的语句和各级被调用函数具有相同的执行顺序;递归函数中,位于递归调用后的语句的执行顺序和各个被调用函数的顺序相反;虽然每一级递归都有自己的变量,但是函数代码并不会得到复制。

Zhenyu_Coder的博客 1604

华为od机试|华为od机试真题2025|华为od题库|华为od机考|2025C卷B卷

华为od机试|华为od机试真题2025|华为od题库|华为od机考|华为od机试|华为od机试真题2025|华为od题库|华为od机考|华为od机试|华为od机试真题2025|华为od题库|华为od机考|华为od机试|华为od机试真题2025|华为od题库|华为od机考|B卷C卷

u014481728的博客 10万+

力扣递归题解——汉诺塔问题详解

递归,回溯一级目录二级目录三级目录 一级目录 二级目录 三级目录

qq_53421929的博客 800

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

详解递归,带 LeetCode 例题

首先说明一个问题,简单阐述一下递归,分治算法,动态规划,贪心算法这几个东西的区别和联系,心里有个印象就好。 递归是一种编程技巧,一种解决问题的思维方式;分治算法和动态规划很大程度上是递归思想基础上的(虽然动态规划的最终版本大都不是递归了,但解题思想还是离不开递归),解决更具体问题的两类算法思想;贪心算法是动态规划算法的一个子集,可以更高效解决一部分更特殊的问题。 分治算法将在这节讲解,以最经典的归...

fdl123456的博客 708

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

LeetCode 206. 反转链表(迭代 + 递归详解)

我们定义递归函数功能:反转以cur为当前节点,pre为前一个节点的链表返回值:反转后的链表的新头节点方法优点缺点迭代空间复杂度 O(1),效率高代码稍显繁琐递归代码简洁,逻辑清晰空间复杂度 O(n),链表过长有栈溢出风险本题是链表操作的入门题,掌握迭代和递归两种写法,能帮助理解指针操作和递归思想。建议初学者先理解迭代法,再逐步消化递归法,重点体会递归函数“不关心中间过程,只相信子调用能完成剩余部分”的思维方式。

2403_88631208的博客 296

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

力扣156题最全解法:如何上下翻转二叉树(递归与迭代方法详解,附图解)

本文详细解读了力扣第156题“上下翻转二叉树”,通过递归法和迭代法两种不同的解法,帮助读者深入理解如何高效地实现树的翻转。希望读者通过本文的学习,能够在力扣刷题的过程中更加得心应手。

10年数据\经营分析经验,现任大厂数据分析负责人 1373

LeetCode 105:从前序与中序遍历构造二叉树,Java 递归解法详解

本文介绍了如何根据前序遍历和中序遍历序列重建二叉树。关键步骤是:1)前序序列首元素为根节点;2)在中序序列中定位根节点,划分左右子树;3)递归处理左右子树。给出了优化的Java实现,使用哈希表存储中序索引,时间复杂度O(n)。常见错误包括混淆遍历顺序、区间处理不当等,需注意前序确定根节点,中序划分左右子树的特性。该算法适用于节点值唯一的情况,空间复杂度主要来自哈希表和递归栈。

weixin_51228134的博客 1万+

力扣394题字符串解码:栈与递归双解法详解与实战技巧

在计算机科学中,栈和递归是处理嵌套结构问题的两大核心思想。栈作为一种后进先出的数据结构,常用于模拟函数调用、管理程序状态,其原理在于通过压栈和弹栈操作保存和恢复上下文。递归则是函数直接或间接调用自身,利用系统调用栈隐式地保存状态,其技术价值在于能以简洁的代码表达复杂的嵌套逻辑。这两种思想在编译器设计、表达式求值、文件路径解析等场景中应用广泛。本文聚焦于力扣394题“字符串解码”,该题要求解析形如`k[encoded_string]`的嵌套编码字符串,正是栈与递归思想的典型应用。通过深入剖析栈方法中**数字累

weixin_30843121的博客 226

力扣226题:翻转二叉树 - 递归解法详解

本文详解力扣226题"翻转二叉树"的递归解法。通过递归遍历交换每个节点的左右子树实现翻转,包含完整注释代码和算法思路。时间复杂度O(n),空间复杂度O(h)。算法分为递归终止条件、节点处理、递归调用和返回结果四个步骤。文章还讨论了迭代实现等优化方向,是掌握二叉树操作和递归思想的经典案例。

2401_86233678的博客 75

LeetCode 394:字符串解码的递归与栈解法详解

在计算机科学中,栈(Stack)是一种基础且重要的数据结构,遵循后进先出(LIFO)原则,常用于处理具有嵌套或回溯性质的问题。其核心原理是通过压栈和出栈操作来管理程序状态或数据顺序。递归则是函数调用自身的一种编程技巧,本质上是系统调用栈的隐式应用,适用于解决可分解为相似子问题的情况。这两种技术在处理嵌套结构解析时展现出极高的技术价值,例如在编译器构建、数据反序列化和模板渲染等场景中,它们能高效地处理括号匹配、状态保存和层级展开。字符串解码问题(LeetCode 394)正是栈与递归思想的经典实战:给定形如`

weixin_31528001的博客 281

【leetcode】算法基础研究——递归详解

前言 相信很多人对于递归都有概念,但是在做题时想用递归时却发现用不好,或者说不知道参数设置,递归方法该写在哪里,这些都是递归相关基础知识不牢靠导致的。 本文为本人自学研究笔记,针对递归常见问题做出一些解释并深入研究,以求达到灵活运用。 什么是递归 看一个典型的问题斐波那契数列: 很明显这是符合递归定义的。 例如树的定义,也是递归。 递归的分类 递归虽然都叫递归,但是区别却很大。 向外递归 这是一种比较简单的递归,例如上方的斐波那契数列就是向外递归,这是因为我们的递归起点实际上是最里面一层(要先计算f(1)

qq_43398404的博客 570

Offer必备算法07_递归_五道力扣题详解(由易到难)

Offer必备算法07_递归_五道力扣题详解(由易到难)(递归算法原理+力扣面试题0806汉诺塔问题+力扣21合并两个有序链表+力扣206反转链表+力扣24两两交换链表中的节点+力扣50Pow(x,n)快速求幂。)

参考书籍:《C语言程序设计》《数据结构》《C++ Primer》《Effective C++》《STL源码剖析》《现代操作系统》《UNIX环境高级编程》《图解TCP/IP》《图解HTTP》《Linux高性能服务器编程》《剑指Offer》《算法导论》 2400

LeetCode 力扣206反转链表(java详解)三种解法:头插法,原地移动链表法,递归法

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 public ListNode reverseList(ListNode head){ /** * 方法一:头插法(遍历原链表,头插到新链表中) */ if(head == null || head.next == null){ return head; } ListNode newHead = null;

m0_48273471的博客 512

LeetCode22 括号生成 递归详解

给定n=3,如何生成[’((()))’, ‘(()())’, ‘(())()’, ‘()(())’, ‘()()()’],直接附上代码(python版) class Solution(object): def generateParenthesis(self, n): """ :type n: int :rtype: List[str] ...

Nichkhun的博客 573

LeetCode 100. 相同的树:两种解法(递归+迭代)详解

本文介绍了LeetCode第100题"相同的树"的两种解法。题目要求判断两棵二叉树在结构和节点值上是否完全相同。递归解法采用分治思想,通过判断当前节点及左右子树是否相同来实现;迭代解法使用栈模拟递归过程,避免栈溢出风险。两种方法时间复杂度均为O(n),但递归空间复杂度为O(h),迭代为O(n)。文章对比了两种解法的优缺点,建议新手先掌握递归再学习迭代,并总结了常见错误点,强调理解"同步遍历"的核心思想对解决类似二叉树问题的重要性。

2401_86788218的博客 736
上一篇: leetcode动态规划之零钱兑换问题
下一篇: cmakelists.txt文件解析
黑猫爱小鹿
博客等级 码龄8年 1万+粉丝 205原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值