二叉树与递归问题

目录

一:求二叉树的深度

 二:二叉树反转

三:二叉树镜像判断 

四:递归的终止条件


用递归解决的问题必须注意的

  • 递归的终止条件,也就是递归的出口(否则:栈溢出)
  • 递归的过程,也就是最小子结构---逻辑

二叉树是天然的递归结构-----结构就是按照递归定义的

一:求二叉树的深度



class Solution {
public:
    int maxDepth(TreeNode* root) {
       int res=0;//定义返回结果
       /*递归终止条件*/
       if(root==NULL) return res;
       /*递归过程--求出左子树高度,求出右子树高度,得出结果*/
       int left=maxDepth(root->left);
       int right=maxDepth(root->right);
       res=max(left,right)+1;//自己占一层
       return res;
    }
};

可以不申请变量

int maxDepth(TreeNode* root) {
       int res=0;//定义返回结果
       /*递归终止条件*/
       if(root==NULL) return res;
       /*递归过程--求出左子树高度,求出右子树高度,得出结果*/
       res=max(maxDepth(root->left),maxDepth(root->right))+1;//自己占一层
       return res;
    }

 二:二叉树反转

TreeNode* invertTree(TreeNode* root) {
        //递归结束条件
       if(root==NULL) return root;
       //递归:左子树和右子树互换
       TreeNode* tmp=invertTree(root->right);
       root->right=invertTree(root->left);
       root->left=tmp;
       return root;
    }

这个思路很清晰:

返回值一定是根节点------为NULL返回,不为空执行递归过程。

在写递归逻辑时,一定从最简单入手。

因为左子树和右子树要交换,定义变量tmp接收右子树的结果,然后把右子树直接传入左子树,最后交换即可。

TreeNode* invertTree(TreeNode* root) {
        //递归结束条件
       if(root==NULL) return root;
       //递归:左子树和右子树互换
      invertTree(root->left);
      invertTree(root->right);
      swap(root->left,root->right);
      return root;
    }

这里不格外定义变量

三:二叉树镜像判断 

给出的函数------bool isSymmetric(TreeNode* root)

思路分析:

这里函数只给出一个变量,但是因为轴的存在,肯定的需要两个指针分别指向一左一右来比较数值

bool twoSymNodes(TreeNode* p,TreeNode* q)

然后只要判断,首先一个为空另一个不为空一定不对称

其次:都不为空时,如果数值不同,一定对称。

最后递归:结束递归(两个指针为空),接受

递归:不断传入p左q右和p右q左

/*
      说白了就是:比较同层次的两个结点p,q
      保证:p左=q右;p右=q左
*/
class Solution {
public:
    bool twoSymNodes(TreeNode* p,TreeNode* q){
    //只考虑存在
    if(p&&!q) return false;
    else if(!p&&q) return false;
    else if(!p&&!q) return true;
    else{
        if(p->val!=q->val) return false;
        return twoSymNodes(p->left,q->right)&&twoSymNodes(p->right,q->left);
    }
    }
    bool isSymmetric(TreeNode* root) {
          //空树对称
          if(root==NULL) return true;
          //比较---最复杂情况(p左=q右 + p右=q左)
          return twoSymNodes(root,root);
    }
};
class Solution {
public:
    bool twoSymNodes(TreeNode* p,TreeNode* q){
          //递归结束的接受状态
          if(!p&&!q) return true;//p,q均为空
          //不接受状态
          if((p&&!q)||(!p&&q)) return false;
          assert(p&&q);
          if(p->val!=q->val) return false;
          else{
              //递归
              return twoSymNodes(p->left,q->right)&&twoSymNodes(p->right,q->left);
          }
    }
    bool isSymmetric(TreeNode* root) {
           return twoSymNodes(root,root);
    }
};

当然可以优化一些细节,比如主程序的root==NULL可以不判断。

这里:传参数量不能满足题目要求,要自己设计函数传参

四:递归的终止条件


分析:

算法思想就是:

在左右子树寻找sum-当前结点值,如果相等了只要该结点是叶子结点就满足题意 

 bool hasPathSum(TreeNode* root, int targetSum) {
           if(root==NULL)  return false;//空树无路径
           if(!root->left&&!root->right&&root->val==targetSum) return true;
           bool a=hasPathSum(root->left,targetSum-(root->val));
           bool b=hasPathSum(root->right,targetSum-(root->val));
           if(a||b) return true;
           else return false;
    }

注意递归终止条件和递归的使用。

bool hasPathSum(TreeNode* root, int targetSum) {
           if(root==NULL) return false;
           if(!root->left&&!root->right) return root->val==targetSum;
           if(hasPathSum(root->left,targetSum-(root->val))) return true;
           if(hasPathSum(root->right,targetSum-(root->val))) return true;
           return false;
    }

 这个写法也满足:叶子结点等于符合条件的值

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值