代码随想录第十七天

第六章 二叉树part04

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

再一次涉及到,什么是高度,什么是深度,可以巩固一下。

题目链接/文章讲解/视频讲解:https://programmercarl.com/0110.%E5%B9%B3%E8%A1%A1%E4%BA%8C%E5%8F%89%E6%A0%91.html

思考:

步骤:

  1. 定义二叉树节点类TreeNode,包括值val、左子树left和右子树right
  2. 创建BalancedBinaryTree类,其中包含一个isBalanced方法用于判断二叉树是否是高度平衡的。
  3. isBalanced方法中,先判断当前节点是否为空,若是则返回true,因为空树是高度平衡的。
  4. 分别计算当前节点的左子树和右子树的高度,可以通过一个辅助方法getHeight实现。
  5. 判断当前节点的左右子树高度差是否不超过1,并且左右子树也是高度平衡的,若满足条件则返回true,否则返回false。
  6. getHeight方法中,递归计算左右子树的高度,并返回较大值加上当前节点1作为当前节点的高度。
  7. main方法中,构建一棵高度平衡的二叉树,并调用isBalanced方法判断是否是高度平衡的。
  8. 输出结果。
  9. 运行程序,得到判断结果。

注意事项:

  1. 对于空树,直接返回true。
  2. 对于非空树,需要计算当前节点的左右子树高度差是否不超过1,并且递归判断左右子树是否也是高度平衡的。
  3. 需要注意空节点的高度为0。

完整代码

// 定义二叉树节点类
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    public TreeNode(int val) {
        this.val = val;
    }
}

public class BalancedBinaryTree {
    public boolean isBalanced(TreeNode root) {
        if (root == null) {
            return true; // 空树是高度平衡的
        }

        int leftHeight = getHeight(root.left); // 计算左子树高度
        int rightHeight = getHeight(root.right); // 计算右子树高度

        // 判断当前节点的左右子树高度差是否不超过1,并且左右子树也是高度平衡的
        return Math.abs(leftHeight - rightHeight) <= 1 && isBalanced(root.left) && isBalanced(root.right);
    }

    private int getHeight(TreeNode node) {
        if (node == null) {
            return 0; // 空节点高度为0
        }
        // 递归计算左右子树的高度,并返回较大值加上当前节点1作为当前节点的高度
        return Math.max(getHeight(node.left), getHeight(node.right)) + 1;
    }

    public static void main(String[] args) {
        // 构建一个高度平衡的二叉树
        TreeNode root = new TreeNode(1);
        root.left = new TreeNode(2);
        root.right = new TreeNode(2);
        root.left.left = new TreeNode(3);
        root.left.right = new TreeNode(3);
        root.right.left = new TreeNode(3);
        root.right.right = new TreeNode(3);

        BalancedBinaryTree balancedBinaryTree = new BalancedBinaryTree();
        System.out.println(balancedBinaryTree.isBalanced(root)); // 输出 true
    }
}

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

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

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

题目链接/文章讲解/视频讲解:https://programmercarl.com/0257.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%89%80%E6%9C%89%E8%B7%AF%E5%BE%84.html

思考:

步骤:

  1. 定义二叉树节点类TreeNode,包括值val、左子树left和右子树right
  2. 创建BinaryTreePaths类,其中包含一个binaryTreePaths方法用于返回从根节点到叶子节点的所有路径。
  3. binaryTreePaths方法中,先创建一个空的路径集合paths
  4. 若根节点为空,直接返回空的路径集合。
  5. 使用深度优先搜索(DFS)遍历二叉树,定义一个辅助方法dfs,参数包括当前节点node、当前路径path和路径集合paths
  6. 若当前节点是叶子节点(即没有左右子树),将当前路径加入结果集。
  7. 若当前节点有左子树,递归调用dfs方法遍历左子树,并将当前节点值加入路径中。
  8. 若当前节点有右子树,递归调用dfs方法遍历右子树,并将当前节点值加入路径中。
  9. main方法中,构建一棵二叉树,并调用binaryTreePaths方法获取从根节点到叶子节点的所有路径。
  10. 输出结果。
  11. 运行程序,得到结果。

注意事项:

  1. 需要使用深度优先搜索(DFS)遍历二叉树,递归地遍历左右子树。
  2. 当遍历到叶子节点时,将当前路径加入结果集。
  3. 路径可以使用字符串来表示,路径中的节点值之间用"->"连接。

完整代码

import java.util.ArrayList;
import java.util.List;

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    public TreeNode(int val) {
        this.val = val;
    }
}

public class BinaryTreePaths {
    public List<String> binaryTreePaths(TreeNode root) {
        List<String> paths = new ArrayList<>();
        if (root == null) {
            return paths;
        }
        dfs(root, "", paths);
        return paths;
    }

    private void dfs(TreeNode node, String path, List<String> paths) {
        if (node.left == null && node.right == null) {
            paths.add(path + node.val); // 当前节点是叶子节点,将路径加入结果集
            return;
        }
        if (node.left != null) {
            dfs(node.left, path + node.val + "->", paths); // 递归遍历左子树
        }
        if (node.right != null) {
            dfs(node.right, path + node.val + "->", paths); // 递归遍历右子树
        }
    }

    public static void main(String[] args) {
        // 构建二叉树
        TreeNode root = new TreeNode(1);
        root.left = new TreeNode(2);
        root.right = new TreeNode(3);
        root.left.right = new TreeNode(5);

        BinaryTreePaths binaryTreePaths = new BinaryTreePaths();
        List<String> paths = binaryTreePaths.binaryTreePaths(root);
        System.out.println(paths); // 输出 ["1->2->5", "1->3"]
    }
}

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

其实本题有点文字游戏,搞清楚什么是左叶子,剩下的就是二叉树的基本操作。

题目链接/文章讲解/视频讲解:https://programmercarl.com/0404.%E5%B7%A6%E5%8F%B6%E5%AD%90%E4%B9%8B%E5%92%8C.html

思考:

步骤:

  1. 定义二叉树节点类TreeNode,包括值val、左子树left和右子树right
  2. 创建SumOfLeftLeaves类,其中包含一个sumOfLeftLeaves方法用于返回所有左叶子之和。
  3. 若根节点为空,直接返回0。
  4. 使用深度优先搜索(DFS)遍历二叉树,定义一个辅助方法dfs,参数包括当前节点node和一个表示当前节点是否为左叶子的布尔值isLeft
  5. 若当前节点是叶子节点(即没有左右子树),判断当前节点是否为左叶子,若是,则返回节点值,否则返回0。
  6. 初始化一个变量sum用于累加左叶子节点的值。
  7. 若当前节点有左子树,递归调用dfs方法遍历左子树,并将当前节点标记为左叶子。
  8. 若当前节点有右子树,递归调用dfs方法遍历右子树,并将当前节点标记为非左叶子。
  9. 将左子树和右子树的结果累加到sum中。
  10. 返回sum作为最终的左叶子之和。
  11. main方法中,构建一棵二叉树,并调用sumOfLeftLeaves方法获取所有左叶子之和。
  12. 输出结果。
  13. 运行程序,得到结果。

注意事项:

  1. 需要使用深度优先搜索(DFS)遍历二叉树,递归地遍历左右子树。
  2. 在递归过程中,需要传入一个额外的参数来表示当前节点是否为左叶子。
  3. 当遍历到叶子节点时,判断当前节点是否为左叶子,若是则返回节点值,否则返回0。
  4. 将左子树和右子树的结果累加到最终的左叶子之和中。

完整代码

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    public TreeNode(int val) {
        this.val = val;
    }
}

public class SumOfLeftLeaves {
    public int sumOfLeftLeaves(TreeNode root) {
        if (root == null) {
            return 0;
        }
        return dfs(root, false); // 初始时没有左叶子,传入false
    }

    private int dfs(TreeNode node, boolean isLeft) {
        if (node.left == null && node.right == null) {
            if (isLeft) {
                return node.val; // 若当前节点是左叶子,返回节点值
            } else {
                return 0; // 若当前节点不是左叶子,返回0
            }
        }

        int sum = 0;
        if (node.left != null) {
            sum += dfs(node.left, true); // 递归遍历左子树,并标记当前节点是左叶子
        }
        if (node.right != null) {
            sum += dfs(node.right, false); // 递归遍历右子树,并标记当前节点不是左叶子
        }
        return sum;
    }

    public static void main(String[] args) {
        // 构建二叉树
        TreeNode root = new TreeNode(3);
        root.left = new TreeNode(9);
        root.right = new TreeNode(20);
        root.right.left = new TreeNode(15);
        root.right.right = new TreeNode(7);

        SumOfLeftLeaves sumOfLeftLeaves = new SumOfLeftLeaves();
        int sum = sumOfLeftLeaves.sumOfLeftLeaves(root);
        System.out.println(sum); // 输出 24
    }
}

  • 10
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值