![5c310d8ef5f028c21467c8b786c48b0d.png](https://i-blog.csdnimg.cn/blog_migrate/15b9276b3a90103be3d9567c237c4969.jpeg)
leetcode
特点1 虽然是从root开始,但是 严重依赖从下到上的反馈的数据 ,例如求tree的高度
题目1 最近公共祖先(LCA)
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
![b8d953a9af924267c859fe190f1f5288.png](https://i-blog.csdnimg.cn/blog_migrate/bb562cbb1d928c8d8ba7c9aa4a57123d.jpeg)
LCA 2和5 返回52次
![e412d56d9395bcdfd38d1da1c3b85dc7.png](https://i-blog.csdnimg.cn/blog_migrate/97ef306a899fcbb18be64a1b79127cd7.jpeg)
8和7 从上到下不知道,在返回过程中才知道
![089d25220a48dba285c6bc78a93b4f87.png](https://i-blog.csdnimg.cn/blog_migrate/eaf3b1d268ce85cc1e49a41fdc929cdc.jpeg)
公共节点
code
/** * 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: TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { if(root ==NULL) { return root; } if(root ==p || root ==q) { return root; } TreeNode* left =lowestCommonAncestor(root->left,p,q); TreeNode* right=lowestCommonAncestor(root->right,p,q); if(left && right) { return root; } //如果都不是返回都不是,如果其中一个是返回其中一个。 //如果2个都是,肯定不进入到这里 方向的选择一个就可以 return left ?left:right; }};
题目2 LeetCode 110. Balanced Binary Tree
![245871be4796707e3dbded9ce500ca8e.png](https://i-blog.csdnimg.cn/blog_migrate/cea36e866d376ff9392563609942c0a1.jpeg)
依赖下面反馈
- 文字描述
递归入栈过程中,是不知道是否满足条件的。
只有出栈时候依赖下面反馈
这里 同时统计每个节点的高度 和是否平衡
而不是从root节点开始判断 是否平衡。
- 代码实现
![39951d983fb31e4858d03f32e5656525.png](https://i-blog.csdnimg.cn/blog_migrate/75c8c8755037c43394cc2570adc2a3b6.jpeg)
递归遍历,依赖下面数据
合并在一起
特点2 从上到下,依赖当前root节点判断
1 翻转等价二叉树
我们可以为二叉树 T 定义一个翻转操作,如下所示:选择任意节点,然后交换它的左子树和右子树。
只要经过一定次数的翻转操作后,能使 X 等于 Y,我们就称二叉树 X 翻转等价于二叉树 Y。
编写一个判断两个二叉树是否是翻转等价的函数。这些树由根节点 root1 和 root2 给出
- 选择任意节点,然后交换它的左子树和右子树
- 左子树和右子树是否继续交换呢? 是否选择了任意节点?
- 等价tree和翻转等级tree的结合
测试
![3aa3600fd99f5973ffb248ea9bb7023c.png](https://i-blog.csdnimg.cn/blog_migrate/8ffd88b14d830ca532577e7660c87600.jpeg)
题目理解错误,以为是全部都翻转了
code
执行用时 : 12 ms/** * 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 flipEquiv(TreeNode* root1, TreeNode* root2) { if(root1 ==NULL && root2 ==NULL) { return true; } if((root1!=NULL && root2==NULL) ||(root2!=NULL &&root1==NULL)||root1->val !=root2->val) { return false; } /** if(root1->left !=root2->right ||root1->right !=root2->left) { return false; }**/ return flipEquiv(root1->left,root2->right) && flipEquiv(root1->right,root2->left) || flipEquiv(root1->left,root2->left) && flipEquiv(root1->right,root2->right); }};func flipEquiv(root1, root2 *TreeNode) bool { if root1 == nil && root2 == nil { return true } if (root1 != nil && root2 == nil) || (root1 == nil && root2 != nil) || root1.Val != root2.Val { return false } if (flipEquiv(root1.Left, root2.Left) && flipEquiv(root1.Right, root2.Right)) || (flipEquiv(root1.Left, root2.Right) && flipEquiv(root1.Right, root2.Left)) { return true } return false}
2 Leetcode 226: 翻转二叉树
![4d616dbe061d283f5013d9b5274f264a.png](https://i-blog.csdnimg.cn/blog_migrate/aadfa83530c031bddfad94202ff57c1a.jpeg)
翻转一棵二叉树
翻转一棵二叉树
备注:
这个问题是受到 Max Howell 的 原问题 启发的 :
谷歌:我们90%的工程师使用您编写的软件(Homebrew),但是您却无法在面试时在白板上写出翻转二叉树这道题,这太糟糕了。
题目理解
潜台词:
一上来不要被题目吓住,考虑到每层都要翻转 ,多么麻烦
这一次和下一层 保持左右转换。没有理解递归真正含义
从上到下遍历过程中 来传递数据。
从上到下递归遍历:
- root保持不变
- 左右子树交换
- 重复步骤1和2
测试
![ec83fafcb9676372b9ce9f384595424e.png](https://i-blog.csdnimg.cn/blog_migrate/e93428903075d23bd3ad802d5774af0b.jpeg)
感觉很简单呀,swap
翻转一棵二叉树
code
class Solution {public: TreeNode* invertTree(TreeNode* root) { if(root == NULL) { return root; } //!!!!! swap TreeNode *temp=root->left; root->left =root->right; root->right=temp; invertTree(root->left); invertTree(root->right); return root; }};
golang
func invertTree(root *TreeNode) *TreeNode {
if root ==nil {
return root
}
//golang 语法就是简洁
root.Left,root.Right=root.Right,root.Left
invertTree(root.Left)
invertTree(root.Right)
return root
}
总结
这几个题目关键 如何理解题意 翻转一棵二叉树,最近公共祖先(LCA)
等等 把复杂问题 变成重复的子问题
- 最近公共祖先(LCA)子问题是什么
如果当前节点如果存在,左右子树是 输入的结果, 当前节点就结果,
如果不是,返回其中任何一个可能,存在一个,或者不存在
返回不同可能就是子问题
- 翻转一棵二叉树 子问题是什么
swap(root) 不考虑层次问题