代码随想录刷题——二叉树day17

76 阅读4分钟

110.平衡二叉树 (优先掌握递归)

平衡二叉树: 是指该树所有节点的左右子树的深度相差不超过 1。

这道题我一开始没有想到所有节点这个重点。于是产生了错误的代码:

错误代码记录:

 /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode() {}
     *     TreeNode(int val) { this.val = val; }
     *     TreeNode(int val, TreeNode left, TreeNode right) {
     *         this.val = val;
     *         this.left = left;
     *         this.right = right;
     *     }
     * }
     */
    class Solution {
        //尝试使用递归
        //然后想法是将一棵树分为两棵树。 然后分别计算左子树和右子树的最大深度
        // int leftMaxDepth=0;
        // int rightMaxDepth=0;
        public boolean isBalanced(TreeNode root) {
            if(root==null)
                return true;
            //如果左右子树的深度超过1,返回false 否则返回true;
            if(Math.abs(calcMaxDepth(root.left,0)-calcMaxDepth(root.right,0))>1)
                return false;
            return true;

        }
        //考虑使用递归方法——后序遍历,通过计算高度来得到深度
        //后序遍历————左右中
        public int calcMaxDepth(TreeNode node,int depth){
            if(node==null)
                return 0;
            //通过递归计算左子树的最大深度
            int depth1=calcMaxDepth(node.left,depth);
            //通过递归计算右子树的最大深度
            int depth2=calcMaxDepth(node.right,depth);
            //计算本节点的最大深度
            return Math.max(depth1,depth2)+1;
        }
    }

上面代码忽略掉的情况如下图所示:比如左子树中的2,它的左子树深度是2,右子树深度是0,所以它并不满足平衡二叉树的定义——所有节点左右子树深度不超过1。

309fd983-046e-42bf-80b2-137550b38a38.png

正确的代码如下:(个人的)

 /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode() {}
     *     TreeNode(int val) { this.val = val; }
     *     TreeNode(int val, TreeNode left, TreeNode right) {
     *         this.val = val;
     *         this.left = left;
     *         this.right = right;
     *     }
     * }
     */
    class Solution {
        //尝试使用递归
        //然后想法是将一棵树分为两棵树。 然后分别计算左子树和右子树的最大深度

        //加入一个关键的全局标志性变量。用于记录这棵树是不是平衡二叉树
        int flag=0;
        public boolean isBalanced(TreeNode root) {
            if(root==null)
                return true;

            calcMaxDepth(root,0);
            if(flag==-1)
                return false;
            return true;

        }
        //考虑使用递归方法——后序遍历,通过计算高度来得到深度
        //后序遍历————左右中
        public int calcMaxDepth(TreeNode node,int depth){
            if(node==null)
                return 0;
            //通过递归计算左子树的最大深度
            int depth1=calcMaxDepth(node.left,depth);
            //通过递归计算右子树的最大深度
            int depth2=calcMaxDepth(node.right,depth);
            //如果左右子树的最大深度之差大于1  那么全局的标志性变量flag变为-1
            if(Math.abs(depth1-depth2)>1){
                flag=-1;
            }
            //计算本节点的最大深度
            return Math.max(depth1,depth2)+1;
        }
    }

上面的代码:一开始我想直接在递归函数中判断,一旦左右子树的最大深度之差大于1,直接跳出整个递归函数(因为此时这棵树一定已经不是平衡二叉树了)。但是递归的特性导致无法直接跳出整个递归函数(除非选择抛出异常,并在调用递归函数的地方捕获这个异常;但这显然不是一个好的方法) 所以选择创建一个“全局变量”用来记录。

257. 二叉树的所有路径 (优先掌握递归)

这是大家第一次接触到回溯的过程, 我在视频里重点讲解了 本题为什么要有回溯,已经回溯的过程。 

如果对回溯 似懂非懂,没关系, 可以先有个印象。 

题目链接/文章讲解/视频讲解:代码随想录

404.左叶子之和 (优先掌握递归)

所谓左叶子的概念:首先它要是个叶子节点,其次它是它父节点的左节点。

/**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode() {}
     *     TreeNode(int val) { this.val = val; }
     *     TreeNode(int val, TreeNode left, TreeNode right) {
     *         this.val = val;
     *         this.left = left;
     *         this.right = right;
     *     }
     * }
     */
    class Solution {
        //考虑使用层序遍历来完成
        public int sumOfLeftLeaves(TreeNode root) {
            //迭代方法层序遍历 一般都会用到队列
            //初始化队列
            Queue<TreeNode> queue=new LinkedList<>();
            //题目中的提示已经说明了节点数在[1,1000],所以root不可能为空
            queue.offer(root);
            int sum=0;  //用于记录树中的左叶子元素总和
            while(!queue.isEmpty()){
                //获取当前层的节点个数
                int len=queue.size();
                while(len>0){
                    TreeNode curNode=queue.poll();
                    len--;
                    //先把下一层的节点入队
                    //左节点入队
                    if(curNode.left!=null)
                        queue.offer(curNode.left);
                    //右节点入队
                    if(curNode.right!=null)
                        queue.offer(curNode.right);
                    if(curNode.left!=null && curNode.left.left==null && curNode.left.right==null){
                        sum+=curNode.left.val;
                    }
                }
            }
            return sum;
        }

    }