day018 第六章 二叉树 part05

news/2024/7/20 20:09:21 标签: 深度优先, 算法, 数据结构

一、513.找树左下角的值

这个题目的主要思路是使用广度优先搜索(BFS)遍历整棵树,最后返回最后一层的最左边的节点的值。具体的实现可以使用队列来存储每一层的节点,并且在遍历每一层节点时,不断更新最左边的节点的值。时间复杂度为O(n),其中n是节点的个数。

二、112.路径总和

这个题目的主要思路是使用深度优先搜索(DFS)遍历整棵树,同时记录到达每个节点时的路径和,如果到达叶子节点时路径和等于给定的目标和,则返回true。具体的实现可以使用递归来实现DFS,同时在每个节点处更新路径和,并且在到达叶子节点时判断路径和是否等于目标和。时间复杂度为O(n),其中n是节点的个数。

三、113.路径总和ii

这个题目的主要思路和112题类似,也是使用DFS遍历整棵树,同时记录到达每个节点时的路径和,并且在到达叶子节点时判断路径和是否等于给定的目标和。不同的是,这个题目需要返回所有满足条件的路径,而不仅仅是返回true或false。具体的实现可以在DFS的过程中使用一个数组来存储当前的路径,并且在到达叶子节点时,如果路径和等于目标和,则将整个路径加入结果列表中。时间复杂度为O(n^2),其中n是节点的个数,主要是因为每次需要复制一份路径数组。

四、106.从中序与后序遍历序列构造二叉树

这个题目的主要思路是使用递归来构建整棵树。具体的实现可以先找到后序遍历序列中的最后一个节点作为根节点,然后在中序遍历序列中找到根节点的位置,从而确定左子树和右子树的范围。然后递归的构建左子树和右子树即可。时间复杂度为O(n),其中n是节点的个数。

五、105.从前序与中序遍历序列构造二叉树

这个题目的主要思路和106题类似,也是使用递归来构建整棵树。具体的实现可以先找到前序遍历序列中的第一个节点作为根节点,然后在中序遍历序列中找到根节点的位置,从而确定左子树和右子树的范围。然后递归的构建左子树和右子树即可。时间复杂度为O(n),其中n是节点的个数。

一、513.找树左下角的值

public int findBottomLeftValue(TreeNode root) {
    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root);
    int res = root.val;
    while (!queue.isEmpty()) {
        int size = queue.size();
        for (int i = 0; i < size; i++) {
            TreeNode node = queue.poll();
            if (i == 0) {
                res = node.val;
            }
            if (node.left != null) {
                queue.offer(node.left);
            }
            if (node.right != null) {
                queue.offer(node.right);
            }
        }
    }
    return res;
}

二、112.路径总和

public boolean hasPathSum(TreeNode root, int sum) {
    if (root == null) {
        return false;
    }
    if (root.left == null && root.right == null) {
        return sum == root.val;
    }
    return hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val);
}

三、113.路径总和ii

public List<List<Integer>> pathSum(TreeNode root, int sum) {
    List<List<Integer>> res = new ArrayList<>();
    List<Integer> path = new ArrayList<>();
    dfs(root, sum, path, res);
    return res;
}

private void dfs(TreeNode root, int sum, List<Integer> path, List<List<Integer>> res) {
    if (root == null) {
        return;
    }
    path.add(root.val);
    if (root.left == null && root.right == null && sum == root.val) {
        res.add(new ArrayList<>(path));
    }
    dfs(root.left, sum - root.val, path, res);
    dfs(root.right, sum - root.val, path, res);
    path.remove(path.size() - 1);
}

四、106.从中序与后序遍历序列构造二叉树

public TreeNode buildTree(int[] inorder, int[] postorder) {
    if (inorder == null || postorder == null || inorder.length != postorder.length) {
        return null;
    }
    int n = inorder.length;
    Map<Integer, Integer> map = new HashMap<>();
    for (int i = 0; i < n; i++) {
        map.put(inorder[i], i);
    }
    return buildTree(inorder, 0, n - 1, postorder, 0, n - 1, map);
}

private TreeNode buildTree(int[] inorder, int inStart, int inEnd, int[] postorder, int postStart, int postEnd, Map<Integer, Integer> map) {
    if (inStart > inEnd || postStart > postEnd) {
        return null;
    }
    int rootVal = postorder[postEnd];
    TreeNode root = new TreeNode(rootVal);
    int index = map.get(rootVal);
    int leftSize = index - inStart;
    root.left = buildTree(inorder, inStart, index - 1, postorder, postStart, postStart + leftSize - 1, map);
    root.right = buildTree(inorder, index + 1, inEnd, postorder, postStart + leftSize, postEnd - 1, map);
    return root;
}

五、105.从前序与中序遍历序列构造二叉树

public TreeNode buildTree(int[] preorder, int[] inorder) {
    if (preorder == null || inorder == null || preorder.length != inorder.length) {
        return null;
    }
    int n = preorder.length;
    Map<Integer, Integer> map = new HashMap<>();
    for (int i = 0; i < n; i++) {
        map.put(inorder[i], i);
    }
    return buildTree(preorder, 0, n - 1, inorder, 0, n - 1, map);
}

private TreeNode buildTree(int[] preorder, int preStart, int preEnd, int[] inorder, int inStart, int inEnd, Map<Integer, Integer> map) {
    if (preStart > preEnd || inStart > inEnd) {
        return null;
    }
    int rootVal = preorder[preStart];
    TreeNode root = new TreeNode(rootVal);
    int index = map.get(rootVal);
    int leftSize = index - inStart;
    root.left = buildTree(preorder, preStart + 1, preStart + leftSize, inorder, inStart, index - 1, map);
    root.right = buildTree(preorder, preStart + leftSize + 1, preEnd, inorder, index + 1, inEnd, map);
    return root;
}

http://www.niftyadmin.cn/n/196054.html

相关文章

深度学习模型评价指标——micro(微平均)/macro(宏平均)

最开始接触micro和macro是通过sklearn.metrics.precision_score&#xff0c;地址如下&#xff1a;precision_score&#xff0c;其中average参数的三个选项&#xff1a;micro、macro、weighted&#xff0c;说明如下。 micro: Calculate metrics globally by counting the total…

用迭代算法求解斐波那契数列

目录 用迭代算法求解斐波那契数列 程序设计 程序分析 用迭代算法求解斐波那契数列 【问题描述】给定n,n小于90,打印出前n+1个斐波那契数。从第0个开始,即F(0)=0,F(1)=1,F(2)=1,... 【

ThreeJS-太阳球围绕旋转(二十四)

数学小知识&#xff1a; 我们根据旋转角度θ可以计算出任意时刻的x,y sinθ y0/r; 因此y0 rsinθ, cosθ x0/r,因此x0 rcosθ, 小拓展&#xff1a; y0^ x0^ - r^2*sinθ^2 r^2*cosθ^2 r^2*(sinθ^2 cosθ^2) r^2; 这也是为什么在极坐标方程中 y0 rsinθ, x0 rcos…

Spring 源码解析 - @Async 注解下的循环依赖问题原理

一、Async 注解下的循环依赖问题 我们都知道 Spring IOC 单例模式下可以帮助我们解决循环依赖问题&#xff0c;比如下面自己依赖自己循环依赖的场景&#xff1a; Component public class TestAsync {ResourceTestAsync async;public void test() {System.out.println("t…

【简单作业向】【Pytorch】猫狗分类

【作业向】 根据给定的猫狗分类数据集&#xff0c;对比 单层CNN模型、从头训练CNN模型(mobileNet)、微调预训练CNN模型(mobileNet)的差异。生成的模型的正向传播图&#xff08;相关方法见我&#xff09;。 使用PyTorch实现。 本文代码&#xff08;数据集在同目录下&#xff09…

【从零开始学习 UVM】12.6、UVM RAL(续更) —— RAL Predictor

文章目录 隐式(自动)预测显式预测在TestBench环境中的插件reg_predictor被动预测UVM RAL 预测器是一个组件,它基于物理接口上的transaction更新镜像值,UVM 提供了“uvm_reg_predictor”基类。 DUT 寄存器可以通过 RAL 方法(如读取和写入)或在目标agent上运行具有有效地址…

Android 开发 错误 Execution failed for task ‘:app:processDebugMainManifest‘.

在使用Android stdio 运行Android 工程时出现Execution failed for task ‘:app:processDebugMainManifest’. 如下图&#xff1a; 错误解决 在配置文件AndroidManifest.xml中添加代码android:exported“true” 关于android:exported"true"的解释&#xff1a; And…

Excel技能之数字函数,数学老师怒扔计算器

同学们在做财务报表&#xff0c;或者一些需要计算数据的工作时&#xff0c;Excel的函数帮很大的忙&#xff0c;不需要用计算器慢慢算&#xff0c;那样太痛苦了。 不用死记硬背&#xff0c;分享到朋友圈&#xff0c;给自己保留一份&#xff0c;需要时&#xff0c;方便查找。关注…