代码随想录算法训练营第十六天| 找树左下角的值、路径总和、 从中序与后序遍历序列构造二叉树

找树左下角的值

题目链接:找树左下角的值

文档讲解:代码随想录

状态:递归没想到中右左的遍历顺序,迭代想出来了

思路:需要找最大深度,然后使用中右左的遍历顺序找最左节点

题解:

java 复制代码
    int res = 0;
    int maxDepth = 0;

    public int findBottomLeftValue(TreeNode root) {
        dfs(root, 0);
        return res;
    }

    //中右左
    public void dfs(TreeNode root, int depth) {
        if (root == null) {
            return;
        }
        depth++;
        dfs(root.left, depth);
        dfs(root.right, depth);
        if (depth > maxDepth) {
            maxDepth = depth;
            res = root.val;
        }
    }

递归题解:层次遍历最后一行第一个数即可

java 复制代码
   public int findBottomLeftValue(TreeNode root) {
        if (root == null) {
            return 0;
        }
        Deque<TreeNode> deque = new LinkedList<>();
        deque.addLast(root);
        int ans = root.val;
        while (!deque.isEmpty()) {
            int size = deque.size();
            TreeNode node = deque.peekFirst();
            ans = node.val;
            while (size-- > 0) {
                deque.pollFirst();
                while (node.left != null) {
                    deque.addLast(node.left);
                }
                while (node.right != null) {
                    deque.addLast(node.right);
                }
            }
        }
        return ans;
    }

路径总和

题目链接:路径总和

文档讲解:代码随想录

状态:还行

思路:看到有返回值,说明可以考虑左右子树进行相同的递归操作,即分别判断它们的子树是否满足条件。

递归题解:

java 复制代码
public boolean hasPathSum(TreeNode root, int targetSum) {
    if (root == null) {
        return false;
    }
    // 如果当前节点是叶子节点,并且从根节点到该节点的路径和等于目标和,则返回true
    // 这里的条件是:当前节点的值等于剩余的目标和,且没有左右子节点
    if (targetSum - root.val == 0 && root.left == null && root.right == null) {
        return true;
    }
    // 递归地检查当前节点的左子树和右子树,看是否存在符合条件的路径
    // 如果左子树或右子树中存在符合条件的路径,则返回true
    // 否则,返回false
    return hasPathSum(root.left, targetSum - root.val) || hasPathSum(root.right, targetSum - root.val);
}

从中序与后序遍历序列构造二叉树

题目链接:从中序与后序遍历序列构造二叉树

文档讲解:代码随想录

状态:没做出来,主要是使用案例中的数组去构建数的时候,误以为inorder中第一个数就是左节点了

思路: 如何根据两个顺序构造一个唯一二叉树?

  • 以 后序数组的最后一个元素为切割点,先切中序数组,根据中序数组,反过来再切后序数组。
  • 一层一层切下去,每次后序数组最后一个元素就是节点元素。

例如:inorder = [9,3,15,20,7] 中序:左中右, postorder = [9,15,7,20,3] 后序:左右中

  • 先看后序中的3肯定是中间结点,然后3在中序中分割,9肯定是左子树,15,20,7肯定属于右子树,
  • 再回到后序,中序中的9是左子树结点,所以在后序中,9是左,15,7,20属于右子树
  • 15,7,20中,20肯定是中间结点,所以回到中序中的15,20,7 肯定15属于左子树,7属于右子树

那么代码应该怎么写呢?

  • 第一步:如果数组大小为零的话,说明是空节点了。
  • 第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。
  • 第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点
  • 第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)
  • 第五步:切割后序数组,切成后序左数组和后序右数组
  • 第六步:递归处理左区间和右区间
  • 注意:要统一分割区间时,是左闭右开还是左闭右闭!!!

题解:

java 复制代码
    Map<Integer, Integer> map;

    public TreeNode buildTree(int[] inorder, int[] postorder) {
        map = new HashMap<>();
        // 用map保存中序序列的数值对应位置
        for (int i = 0; i < inorder.length; i++) {
            map.put(inorder[i], i);
        }
        //前闭后开
        return findNode(inorder, 0, inorder.length, postorder, 0, postorder.length);
    }


    public TreeNode findNode(int[] inorder, int inBegin, int inEnd, int[] postorder, int postBegin, int postEnd) {
        //参数里面的范围都是前闭后开
        if (inBegin >= inEnd || postBegin >= postEnd) {
            // 不满足左闭右开,说明没有元素,返回空树
            return null;
        }
        //找到后序遍历中的最后一个元素
        int rootIndex = map.get(postorder[postEnd - 1]);//例如,找到后序中的3在中序中的位置为1
        //构造结点
        TreeNode root = new TreeNode(inorder[rootIndex]);
        // 保存中序左子树个数,用来确定后序数列的个数
        int lenOfLeft = rootIndex - inBegin;//例如,1-0 = 1
        // inorder:[9] postorder:[9]
        root.left = findNode(inorder, inBegin, rootIndex, postorder, postBegin, postBegin + lenOfLeft);
        // inorder:[15,20,7] postorder:[15,7,20]
        root.right = findNode(inorder, rootIndex + 1, inEnd, postorder, postBegin + lenOfLeft, postEnd - 1);
        return root;
    }
相关推荐
是小Y啦9 分钟前
leetcode 106.从中序与后续遍历序列构造二叉树
数据结构·算法·leetcode
liuyang-neu19 分钟前
力扣 42.接雨水
java·算法·leetcode
y_dd26 分钟前
【machine learning-12-多元线性回归】
算法·机器学习·线性回归
m0_6312704026 分钟前
标准c语言(一)
c语言·开发语言·算法
万河归海42826 分钟前
C语言——二分法搜索数组中特定元素并返回下标
c语言·开发语言·数据结构·经验分享·笔记·算法·visualstudio
小周的C语言学习笔记31 分钟前
鹏哥C语言36-37---循环/分支语句练习(折半查找算法)
c语言·算法·visual studio
y_dd31 分钟前
【machine learning-七-线性回归之成本函数】
算法·回归·线性回归
小魏冬琅1 小时前
K-means 算法的介绍与应用
算法·机器学习·kmeans
凌肖战2 小时前
力扣上刷题之C语言实现(数组)
c语言·算法·leetcode
秋夫人2 小时前
B+树(B+TREE)索引
数据结构·算法