目录
用递归解决的问题必须注意的:
二叉树是天然的递归结构-----结构就是按照递归定义的 |
一:求二叉树的深度
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; }
这个写法也满足:叶子结点等于符合条件的值