Leetcode 递归题目总结

    Leetcode上的递归一共有45道,现在刷了一半了,花一天半时间复盘,之后进入下一类题型。

实质

把问题转化为规模缩小了的同类问题的子问题,是一种直接或者间接调用自身的算法。

特点

  • 必须有一个明确的递归结束条件,称为递归出口
  • 递归算法解题通常显得很简洁,但递归算法解题的运行效率较低。所以一般不提倡用递归算法设计程序。(比如在leetcode上用递归求斐波那契数列就溢出)
  • 在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。所以一般不提倡用递归算法设计程序
  • 原理就是一个栈
  • 好处是:写代码迅速,代码简洁,坏处是:效率低

适合题型

树、二叉树(二叉平衡树、二叉搜索树、满二叉树、普通二叉树)、链表、斐波那契、阶乘

答题模板

思考以下三个问题:

(1) 找终止条件

(2) 找返回值

(3) 本级递归应该做什么。不要考虑过多,只关心本级干什么

这个答题模板参考自三道题套路解决递归问题, 在leetcode的评论区上发现的宝藏,起初我做递归题思路是一团乱麻,看了这个博主的文章受益良多。

可能会用到的技巧

  • 高度平衡二叉树定义为:一个二叉树每个节点的左右两个子树的高度差的绝对值不超过 1 。
  • 一颗平衡二叉树的左右子树为平衡二叉树’
  • 二叉搜索树的中序遍历刚好是升序

Leetcode按照类型分组

注意,这些题有些出自深度优先遍历的分组里,要牢记DFS和递归的关系:

DFS可以用递归实现,也可以不用递归实现。

1.二叉树
110. 平衡二叉树

题目描述
给定一个二叉树,判断它是否是高度平衡的二叉树。本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点的左右两个子树的高度差的绝对值不超过 1 。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
 //深度优先遍历求树高,再根据平衡二叉树的定义判断是否平衡
 /*
 递归停止条件:节点为空;树不平衡
 返回什么:真假
 本级干什么:判左右子树高度相差值<=1 ,判左右子树是否是平衡树
 */
 class Solution {
public:
    bool isBalanced(TreeNode* root) {
        //左右子树均是平衡二叉树
        if(root==nullptr)
            return true;
        if(abs(depth(root->left)-depth(root->right))>1){
            return false;
        }
        return isBalanced(root->left)  &&  isBalanced(root->right);
    }
    int depth(TreeNode* root)
     {
        if(root==nullptr){
            return  0;
        }
        return max(depth(root->left),depth(root->right))+1;
    }
};

111. 二叉树的最小深度
题目描述
给定一个二叉树,找出其最小深度。最小深度是从根节点到最近叶子节点的最短路径上的节点数量。说明:叶子节点是指没有子节点的节点。
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
 /*思路:
 终止条件:走到空节点
 返回什么:返回左右子树上的最小深度+1
 本级递归应该做什么:求左右子树上的最小深度
 */
class Solution {
public:

    int minDepth(TreeNode* root) {
        if(root==nullptr)  return  0;
         int left=minDepth(root->left);
         int right=minDepth(root->right);
         if(left==0){     //应对只有右子树的情况
             return right+1;
         }
         if(right==0){  //应对只有左子树的情况
             return left+1;
         }
         return min(right,left)+1;
    }
    
};
226. 翻转二叉树
翻转一棵二叉树。

示例:

输入:

     4
   /   \
  2     7
 / \   / \
1   3 6   9
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
/*
递归终止条件:root为空
返回什么:已经翻转完左右子树的根节点
本级递归做什么: 进行左右子树的翻转,左右子树的根节点的交换
*/
class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if(root==nullptr) return  root;
        
        root->left=invertTree(root->left);
        root->right=invertTree(root->right);

        TreeNode* temp=root->right;
        root->right=root->left;
        root->left=temp;

        return root;

        
    }
};
617. 合并二叉树
给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。

你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。

示例 1:

输入: 
	Tree 1                     Tree 2                  
          1                         2                             
         / \                       / \                            
        3   2                     1   3                        
       /                           \   \                      
      5                             4   7                  
输出: 
合并后的树:
	     3
	    / \
	   4   5
	  / \   \ 
	 5   4   7
注意: 合并必须从两个树的根节点开始。
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
 /*
 递归停止条件:root1和root2有一个为空
 返回什么:返回合并后的树的根节点
 本级递归应该做什么: 合并两个二叉树:
 */
class Solution {
public:
    TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
        if(!root1)   return root2;
        if(!root2)   return root1;
        
        root1->left=mergeTrees(root1->left,root2->left);
        root1->right=mergeTrees(root1->right,root2->right);
        root1->val=root1-&
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值