笔记依照于东哥所著算法
文章目录
二叉树类的题如何思考
二叉树解题的思维模式分两类:
1、是否可以通过遍历一遍二叉树得到答案?如果可以,用一个 traverse 函数配合外部变量来实现,这叫「遍历」的思维模式。
2、是否可以定义一个递归函数,通过子问题(子树)的答案推导出原问题的答案?如果可以,写出这个递归函数的定义,并充分利用这个函数的返回值,这叫「分解问题」的思维模式。
无论使用哪种思维模式,你都需要思考:
如果单独抽出一个二叉树节点,它需要做什么事情?需要在什么时候(前/中/后序位置)做?其他的节点不用你操心,递归函数会帮你在所有节点上执行相同的操作。
- 在思考二叉树的时候,通常都是拿出某一个节点来思考如下问题
1,我从这个节点想要得到什么
2,我要从这个节点的左孩子右孩子得到什么
3,是从这个节点推导左右孩子,还是从左右孩子推导该节点(这决定了使用什么遍历方式)
4,争对这个节点来思考可能性
例题
二叉树的直径
这题的思路就是算出左子树的最大值,然后加上右子树的大值
按照上面的步骤来推导:
1,我从这个节点想得到过这个节点的最大直径
2,他的左子树最大的深度,和右子树的最大的深度
3,既然是要得到左子树右子树的深度,最好的方法就是自下而上遍历,就是后序遍历
4,对于这个节点,有可能不是经过这个节点获得最大直径,所以,要声明一个变量来更新最大值
上代码:
//更新最大值
private int max;
public int diameterOfBinaryTree(TreeNode root) {
//首先思考,对于每个节点来说,他的直径就是左子树的最大深度加上右子树的最大深度
if(root==null) return 0;
int a=order(root);
return max;
}
public int order(TreeNode root){
if(root==null) return 0;
int leftmax=order(root.left);
int rightmax=order(root.right);
max=Math.max(max,leftmax+rightmax);
return Math.max(leftmax,rightmax)+1;
}
这题可以从图看出思路,就是先把左右节点的子树交换,然后依次重复这个步骤
继续按照上面的步骤分析
1,我要从这个节点得到两个子树的信息,然后进行交换
2,左右子树同1一样的思路
3,对于交换可以看出,是自顶向下的交换,从底向上,跟本不好实现,多以遍历方式就是先序遍历
4,没什么要考虑的,就算为空的话,直接返回就可以
上代码:
class Solution {
public TreeNode invertTree(TreeNode root) {
//翻转二叉树就是从头部就把左右子树进行交换,然后重复这个步骤
//从上至下,所以优先烤炉用先序遍历
if(root==null) return null;
//创建一个临时节点,来进行交换
TreeNode node=new TreeNode();
node=root.left;
root.left=root.right;
root.right=node;
//上面属于前序遍历代码区
invertTree(root.left);
invertTree(root.right);
return root;
}
}