二叉树套路解题方法(适合树形DP问题)
验证一棵树是否为满二叉树
通过例子,VerifyFullBinaryTree来说明过程,一棵树是否为满二叉树,正常思想是遍历整颗树,得到树的高度以及树的总结点个数。所以这里我们需要构建一个类,类里面包含了所需要的信息,这里也就是树的高度以及节点个数。代码如下
//需要返回的信息的类.
public static class Info{
public int height;
public int nodes;
public Info(int height, int nodes) {
this.height = height;
this.nodes = nodes;
}
}
然后写模板代码。
public static boolean isFullBinaryTree(TreeNode node){
if (node == null)
return true;
Info data = process(node);
/**
*位运算,<<跟>>,<<左移,一位表示乘以2,>>右移,一位表示除2
*这里满二叉树是节点nodes等于2的h次方-1,h是树的高度,
*这里1 << data.height,表示 1 左移 data.height 位
*也就是1 * 2 * 2 * 2 ...(data.height个2相乘)
*/
return data.nodes == (1 << data.height - 1);
}
// 这里,递归返回,思考需要什么信息.
private static Info process(TreeNode node) {
//首先递归出口,返回树的高度跟节点个数
if (node == null){
return new Info(0,0);
}
// int height;
// int nodes;
// return new Info(height,nodes);
//都是这样写,具体就是怎 么获得height跟nodes.
//先拿到左右子树的信息,再构建整棵树的信息.
Info leftData = process(node.left);
Info rightData = process(node.right);
int height = Math.max(leftData.height,rightData.height) + 1;
//+1 加上自己的这个节点.
int nodes = leftData.nodes + rightData.nodes + 1;
return new Info(height,nodes);
}
验证一棵树是否为平衡二叉树
给定一棵树,判断其是否为平衡二叉树,通过思考我们可以知道,一颗平衡二叉树需要它的左右孩子也都是平衡二叉树。平衡二叉树的定义是,要么是一颗空树,要么它的左右两个子树的高度差的绝对值不超过1。通过平衡二叉树的性质,我们思考我们递归需要返回哪些信息,1、首先是左右孩子的高度height;2、然后还需要知道左右孩子是不是也是平衡二叉树。所以我们定义一个信息类,里面包含两个信息,boolean isBalanced 和 int height。
public static class ReturnType{
public boolean isBalanced;
public int height;
public ReturnType(boolean isBalanced, int height) {
this.isBalanced = isBalanced;
this.height = height;
}
}
然后依旧按照套路,写模板代码。
public static isBalanced(TreeNode node){
return process(node).isBalanced;
}
private ReturnType process(TreeNode node){
//递归出口,如果是空树,返回是平衡二叉树,高度0
if(node == null)
return new ReturnType (true,0);
ReturnType leftProcess = process(root.left);
ReturnType rightProcess = process(root.right);
int height = Math.max(leftProcess.height,rightProcess.height) + 1;
boolean isBalanced = leftProcess.isBalanced && rightProcess.isBalanced &&
Math.abs(leftProcess.height - rightProcess.height) < 2;
return new ReturnType(isBalanced,height);
}
小总结
绝大部分二叉树的问题都可以用此套路去解决。具体来说,只要该问题可以通过返回其左右孩子的一些结果,然后整合在一起可以得出解,就可以用这个套路,需要变动的就是我们需要思考需要返回哪些信息。其实这就是动态规划的思想,一层一层往上返回,最后得到最终解。不适用的情况,比如,题目是,二叉树每个节点都有一个值,我们需要返回该二叉树上的中位数,这是就不可以用这个套路去解题,因为按照上面的思想,我们可以得到其左右孩子的中位数的值,然后再整合在一起,然而其左子树的中位数,跟右孩子的中位数,整合完之后也得不到整棵树的中位数。