代码随想录算法训练营day17 | 110.平衡二叉树 257. 二叉树的所有路径 404.左叶子之和

70 阅读3分钟

110.平衡二叉树

给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。

110. 平衡二叉树 - 力扣(Leetcode)

思路

根据平衡二叉树的定义,要判断一棵树是否平衡需要判断该树所有的子树是否平衡,只要有一棵子树不平衡,该树就不是平衡二叉树;
对于每一棵子树,要判断其是否平衡需要满足以下三个条件:

  1. 左子树是平衡二叉树;
  2. 右子树是平衡二叉树;
  3. 左右子树的高度差不超过1

在进行递归遍历时,如果当前子树不是平衡二叉树,则返回-1;在计算左、右子树高度时,如果结果为-1,则意味着这棵树已经不是平衡二叉树了,不用再计算它的高度,返回-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 {
    public boolean isBalanced(TreeNode root) {
        return getDepth(root) == -1 ? false : true;
    }

    private int getDepth(TreeNode root){

        if(root == null){
            return 0;
        }

        int leftDepth=0,rightDepth=0;

        leftDepth = getDepth(root.left);

        if(leftDepth == -1){
            return -1;
        }

        rightDepth = getDepth(root.right);

        if(rightDepth == -1){
            return -1;
        }

        return Math.abs(leftDepth - rightDepth) > 1 ? -1 : 1 + Math.max(leftDepth,rightDepth);

    }
}

257. 二叉树的所有路径

给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。
叶子节点 是指没有子节点的节点。

257. 二叉树的所有路径 - 力扣(Leetcode)

思路

要计算二叉树的路径,从根结点出发,到达叶子结点,遍历一定是从父结点到子结点的,因此,要采用中左右前序遍历的方式进行。
参数:当前节点node,用于存储各路径的res,和当前路径path;
终止条件:如果终止条件落到null结点,那么路径将从叶子结点进入左孩子的null和右孩子的null,这条路径将被记录两次,不符合要求。因此,该算法的终止条件是当前结点是叶子结点。

过程:

  • 当前结点加入路径中,如果当前结点有左孩子,则进入左孩子的路径中;如果当前结点有右孩子,则进入右孩子的路径中;
  • 当路径遍历完成,将当前结果移出路径,因为使用同一个path来标识路径,如果不移除当前结点,会对后续其他路径的记录产生影响。

代码

/**
 * 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 List<String> binaryTreePaths(TreeNode root) {
        List<String> res = new ArrayList<>();
        StringBuilder sb = new StringBuilder();
        getPaths(root,res,sb);

        return res;

    }

    private void getPaths(TreeNode node,List<String> res,StringBuilder path){

        if(node.left == null && node.right == null){
            // 到达叶子结点
            // 将叶子结点加入到路径中
            int length = path.length();
            path.append("->");
            path.append(node.val);

            // 一条路径遍历完成
            res.add(new String(path.substring(2)));

            // 回退
            path.delete(length,path.length());

            return;
        }

        int length = path.length();

        path.append("->");
        path.append(node.val);

        if(node.left != null){
            getPaths(node.left,res,path);
        }

        if(node.right != null){
            getPaths(node.right,res,path);
        }

        // 回退
        path.delete(length,path.length());

    }
}

404.左叶子之和

给定二叉树的根节点 root ,返回所有左叶子之和。

404. 左叶子之和 - 力扣(Leetcode)

思路

对于二叉树上的一个节点,

  • 如果它的左孩子存在,且这个左孩子是一个叶子结点,那么这个节点的左叶子之和为 左孩子的值 + 右子树的左叶子之和
  • 如果它的左孩子不是叶子节点,那么这个节点的左叶子之和为 左子树的左叶子之和 + 右子树的左叶子之和
  • 由此可见,深度遍历的遍历方式应该是左右中后序遍历
  • 如果该节点为null,则遍历到终止条件,该节点的左叶子之和为0

代码

/**
 * 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) {
        return getSumofLeftLeaves(root);
    }

    private int getSumofLeftLeaves(TreeNode node){
        if(node == null){
            return 0;
        }

        int leftSum=0,rightSum=0;

        leftSum = getSumofLeftLeaves(node.left);
        
        rightSum = getSumofLeftLeaves(node.right);

        if(node.left!=null && node.left.left==null && node.left.right==null){
            return rightSum + node.left.val;
        }

        return leftSum + rightSum;
        
        
    }
}