• 代码随想录Day15 二叉树 LeetCodeT513 找树左下角的值 T112路径总和 T106 从中序和后序遍历构造二叉树


    以上思路来自于:代码随想录 (programmercarl.com)

    LeetCode T513 找树左下角的值

    题目思路:

    本题思路:这题我们使用递归法和迭代法解决问题

    注意:左下角的值不一定就是一直向左遍历的叶子结点的值,首先可以确定是最后一行的第一个叶子结点的值,也就是最大深度的叶子结点的值

    定义最大深度Deep变量,返回值result

    1.递归法

    前序遍历为例

    1.1 确定递归的返回值和参数类型

    我们这里不需要返回值,传入参数是节点和深度

    void travelsal(TreeNode node,int deep)

    1.2 确定终止条件

    这里我们遇到一次叶子结点就更新一次最大深度,并记录下该节点的val

    1. if(node.left == null && node.right == null)
    2. {
    3. if(deep>Deep)
    4. {
    5. Deep = deep;
    6. result = node.val;
    7. }
    8. }

    1.3 实现一次递归

    1. if(node.left != null)
    2. {
    3. travelsal(node.left,deep+1);
    4. }
    5. if(node.right != null)
    6. {
    7. travelsal(node.right,deep+1);
    8. }

    2.迭代法

    思路:使用层序遍历,找到最后一行,记录下最左边节点的数值

    1.使用队列结构,队列不为空就继续,先加入根节点,接着我们用一个临时节点记录一下正在遍历的节点,方便取值,使用for循环,遍历每一层,记录下每一层第一个值,如果不是叶子节点就继续入队,详细思路可以看 层序遍历章节

    代码解析:

    1. public int findBottomLeftValue(TreeNode root) {
    2. //迭代法
    3. int result = 0;
    4. Queue que = new LinkedList<>();
    5. que.offer(root);
    6. while(!que.isEmpty())
    7. {
    8. int size = que.size();
    9. for(int i = 0;i
    10. {
    11. TreeNode tmp = que.poll();
    12. if(i == 0)
    13. {
    14. result = tmp.val;
    15. }
    16. if(tmp.left != null)
    17. {
    18. que.offer(tmp.left);
    19. }
    20. if(tmp.right != null)
    21. {
    22. que.offer(tmp.right);
    23. }
    24. }
    25. }
    26. return result;
    27. }
    28. }

    题目代码:

    1. class Solution {
    2. int Deep = -1;
    3. int result = 0;
    4. public int findBottomLeftValue(TreeNode root) {
    5. result = root.val;
    6. travelsal(root,0);
    7. return result;
    8. }
    9. void travelsal(TreeNode node,int deep)
    10. {
    11. if(node == null)
    12. {
    13. return;
    14. }
    15. if(node.left == null && node.right == null)
    16. {
    17. if(deep>Deep)
    18. {
    19. Deep = deep;
    20. result = node.val;
    21. }
    22. }
    23. if(node.left != null)
    24. {
    25. travelsal(node.left,deep+1);
    26. }
    27. if(node.right != null)
    28. {
    29. travelsal(node.right,deep+1);
    30. }
    31. }
    32. }

    LeetCode T112 路径总和

    题目链接:112. 路径总和 - 力扣(LeetCode)

    题目思路:

    思路其实很简单,我们只需要遍历二叉树在叶子节点的时候判断即可,但是还是有很多细节需要注意,我们分一下几步操作,判断节点是否为空,减去该节点的值,判断叶子结点的值,下面就是递归的过程

    1.判断头结点

    1. if(root == null)
    2. {
    3. return false;
    4. }

    2.叶子节点

    1. //叶子结点
    2. if(root.left == null && root.right == null)
    3. {
    4. return targetSum == 0;
    5. }

    3.递归过程

    1. //递归逻辑
    2. if(root.left != null)
    3. {
    4. boolean left = hasPathSum(root.left,targetSum);
    5. if(left)
    6. {
    7. return true;
    8. }
    9. }
    10. if(root.right != null)
    11. {
    12. boolean right = hasPathSum(root.right,targetSum);
    13. if(right)
    14. {
    15. return true;
    16. }
    17. }

    注:我们这里用目标值一直往下减,如果到叶子节点发现值减到0就说明成功了,注意回溯的过程这里省略了.

    题目代码:

    1. class Solution {
    2. public boolean hasPathSum(TreeNode root, int targetSum) {
    3. //终止条件
    4. if(root == null)
    5. {
    6. return false;
    7. }
    8. targetSum -= root.val;
    9. //叶子结点
    10. if(root.left == null && root.right == null)
    11. {
    12. return targetSum == 0;
    13. }
    14. //递归逻辑
    15. if(root.left != null)
    16. {
    17. boolean left = hasPathSum(root.left,targetSum);
    18. if(left)
    19. {
    20. return true;
    21. }
    22. }
    23. if(root.right != null)
    24. {
    25. boolean right = hasPathSum(root.right,targetSum);
    26. if(right)
    27. {
    28. return true;
    29. }
    30. }
    31. return false;
    32. }
    33. }

    T106 从中序和后序遍历构造二叉树

    题目链接:106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)

    题目思路:

    这题思路较为简单,代码较长,我们举一个例子

    我们首先根据后序的左右中来切割中序数组,就能知道9是左子树,15 20 7是右子树

    然后根据右子树判断中节点是20,20的左节点是15右节点是7,我们就能唯一确定一个二叉树

    这里我们分为以下几步处理

    1.创建一个map来便于查找

    2.将inorder的数据保存到map中 (key是数值,value是下标)

    3.接着我们使用递归来实现

    4.确定参数和返回值

    public TreeNode findNode(int[] inorder, int inBegin, int inEnd, int[] postorder, int postBegin, int postEnd) 

    5.终止条件(注意这里切分区间要统一,使用闭区间还是左开右闭区间)

    1. if (inBegin >= inEnd || postBegin >= postEnd) { // 不满足左闭右开,说明没有元素,返回空树
    2. return null;
    3. }

    6.单次递归

    1. int rootIndex = map.get(postorder[postEnd - 1]); // 找到后序遍历的最后一个元素在中序遍历中的位置
    2. TreeNode root = new TreeNode(inorder[rootIndex]); // 构造结点
    3. int lenOfLeft = rootIndex - inBegin; // 保存中序左子树个数,用来确定后序数列的个数
    4. root.left = findNode(inorder, inBegin, rootIndex,
    5. postorder, postBegin, postBegin + lenOfLeft);
    6. root.right = findNode(inorder, rootIndex + 1, inEnd,
    7. postorder, postBegin + lenOfLeft, postEnd - 1);

    题目代码:

    1. class Solution {
    2. Map map;
    3. public TreeNode buildTree(int[] inorder, int[] postorder) {
    4. map = new HashMap<>();
    5. for(int i = 0;i
    6. {
    7. map.put(inorder[i],i);
    8. }
    9. return FindOrder(inorder,0,inorder.length,postorder,0,postorder.length);
    10. }
    11. public TreeNode FindOrder(int[] inOrder,int inBegin,int inEnd,int[] postOrder,int postBegin,int postEnd)
    12. {
    13. //结束条件,这里我使用左闭右开写
    14. if(inBegin>=inEnd || postBegin>=postEnd)
    15. {
    16. return null;
    17. }
    18. //找到后序在中序的位置
    19. int index = map.get(postOrder[postEnd - 1]);
    20. //构造节点
    21. TreeNode root = new TreeNode(inOrder[index]);
    22. //保存中序左子树的个数,用来确定后序的区间
    23. int lenOfLeft = index - inBegin;
    24. root.left = FindOrder(inOrder,inBegin,index,postOrder,postBegin,postBegin+lenOfLeft);
    25. root.right = FindOrder(inOrder,index+1,inEnd,postOrder,postBegin+lenOfLeft,postEnd-1);
    26. return root;
    27. }
    28. }

  • 相关阅读:
    计算机毕业设计ssm餐饮外卖系统v22fo系统+程序+源码+lw+远程部署
    C# 后台处理 webp图片
    Linux系统编程_文件编程第2天:写整数、结构体,fopen等
    基于SpringBoot的个人博客系统设计与实现
    Toward Fast, Flexible, and Robust Low-Light Image Enhancement
    用户留存为何重要?
    python协整与异步调用,压榨程序的摸鱼时间——使用异步编写需要循环执行的程序,并获取返回值(2)
    单调栈的相关应用
    节约软件开发成本,关键在这儿。
    目标检测系列——Fast R-CNN
  • 原文地址:https://blog.csdn.net/qiuqiushuibx/article/details/133735315