二叉树题型思考总结

我们从两道题出发总结二叉树题型思考方向

leetcode110. 平衡二叉树:

题目很容易,讲这道题是为了记录一下写递归函数的技巧
首先如果发现该题后序遍历,自底向下返回子树高度。那么易解

class Solution {
    public boolean isBalanced(TreeNode root) {
        return recur(root) != -1;
    }

    
    //函数作用:求子树高度,不是平衡树时返回-1
    private int recur(TreeNode root) {
        //终止条件,没有节点子树自然高度为0
        if (root == null) return 0;
        
        //根据函数作用可以知道函数会返回left和right,不要想函数怎么求的,当作黑盒,然后利用left和right去写代码完成函数
        int left = recur(root.left);
        int right = recur(root.right);


        //已知left和rigth,决定返回值。
        //若子树是平衡树 返回该子树的子树的最大高度+1( max(left, right) + 1)  若不是返回-1。
        //这是根据函数作用来写的
        if(left == -1) return -1;
        if(right == -1) return -1;        
        return Math.abs(left - right) < 2 ? Math.max(left, right) + 1 : -1;
    }
}

但是如果没想到怎么办呢?也是可以做的,我上面的代码注释就是没想到顺序的注释,我们当成一个递归问题即可

首先明确函数作用:求子树高度(是平衡树返回高度,不是返回-1),明确了之后我们假设函数已经写完了,成为了一个API了,接下来我们利用这个API写完我们的函数。
写函数时当作我们在处理一个节点即可
1.终止条件,没有节点子树自然高度为0
2.调API得到left和right
3.根据left和right决定该节点返回值
一个节点的处理写完了,题目自然做出来了,最后在isBalanced方法里面再最后调一次API求最大的一个树高度即可。

ps:如果思维老是会随着递归一次次进去,再来个小技巧:取特殊情况,我们把树想成是一个两层的二叉树来写代码。毕竟人脑能堆几个栈啊,两层到顶了。
证明:想想就知道能求解两层满二叉树的代码原封不动就能求解任何树,这就是这么想正确的原因。

leetcode124. 二叉树中的最大路径和

以该题提出思考总纲
两个方向1.确定遍历顺序2.当作递归问题

  1. 先思考是先中后序那个?举例易知节点需要左右子树信息则后序,节点不需要左右子树信息甚至能给左右子树信息则先序,中序同理。想清楚序后就直接套模板即可,稍微难点的题型无非是返回值是int。
  2. 想不出什么序则换个方向,当作递归问题思考,如上题110所言

之前110用的第二个思考方向,这题可以尝试使用第一个:节点需要左右子树信息必然后序遍历,套模板后序遍历一遍所有节点,每个节点处检查该节点的最大路径和,取max即树的最大路径和,思考负担更小。
下面代码注释思考了两个方向

class Solution {
    
    private int ret = Integer.MIN_VALUE;
    
    public int maxPathSum(TreeNode root) {
        //对于任意一个节点,其最大路径和一定是 左子树(<0舍去)+右子树(<0舍去)+该节点
        getMax(root);
        return ret;
    }
    
    //方向1:节点需要左右子树信息必然后序遍历,套模板后序遍历一遍所有节点,每个节点处检查该节点的最大路径和,取max即树的最大路径和
    //方向2:函数作用:返回该节点为根的最大路径和=左右之中的最大路径+该节点值。注意实际最大路径和还要考虑r.val + left + right,但是对于上一层这个路径是不可能构成上一层的最大路径的,所以返回时不返回这种可能
    private int getMax(TreeNode r) {
        if(r == null) return 0;
        int left = Math.max(0, getMax(r.left)); // 如果子树路径和为负则应当置0表示最大路径不包含子树
        int right = Math.max(0, getMax(r.right));
        ret = Math.max(ret, r.val + left + right); // 判断在该节点包含左右子树的路径和是否大于当前最大路径和
        return Math.max(left, right) + r.val;//left和right只能取一个,
    }
}

你可能感兴趣的:(算法,算法,二叉树,leetcode)