代码随想录day18| 二叉树part05(513、 112.113、105.106)

97 阅读2分钟

513. 找树左下角的值

给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。

假设二叉树中至少有一个节点。

思路: 在递归时传入当前节点的深度,根节点设为1和初始的0区分。当遍历到节点的深度更大时,进行替换。(先序遍历,所以最大的第一个节点一定是左节点) 另:可以使用层序遍历。


/**
 * @param {TreeNode} root
 * @return {number}
 */
var findBottomLeftValue = function(root) {
//如果root时传0 ,可以在这里增加判断
    // if(!root.left && !root.right) return root.val
    let nodeData = [0,0] //记录节点的val和深度
    const traversal = (node,  h)=>{
        if(node === null) return
        if( !node.left && !node.right){
            if(h > nodeData[1]){
                // 因为是先递归左子树,所以相同值的时候不替换,只有当前h更大才替换
                nodeData = [node.val, h]
            }
        }
        traversal(node.left,  h+1)
        traversal(node.right,  h+1)
    }
    traversal(root,  1)
    return nodeData[0]
};

112. 路径总和

给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。

叶子节点 是指没有子节点的节点。

image.png

思路:前序遍历,先进行计算sum,如果不满足,则继续递归。

/**
 * @param {TreeNode} root
 * @param {number} targetSum
 * @return {boolean}
 */
var hasPathSum = function(root, targetSum) {
    if(root === null) return false
    let flag = false
    const buildPath = (node, sum)=>{
        if(flag) return true
        if(node === null) return 0
        const cur = sum + node.val
        if(!node.left && !node.right && cur === targetSum){
            flag = true
        }
        buildPath(node.left, cur)
        buildPath(node.right, cur)
    }
    buildPath(root, 0)
    return flag
};

113. 路径总和 II

给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。

叶子节点 是指没有子节点的节点。

思路:此题需要获取path,则在递归同时传递path,符合条件的保存

/**
 * @param {TreeNode} root
 * @param {number} targetSum
 * @return {number[][]}
 */
var pathSum = function(root, targetSum) {
    if(root === null) return []
    const paths = []
    const buildPath = (node, sum,path)=>{
        if(node === null) return []
        const cur = sum + node.val
        const curPath = [...path, node.val]
        if(!node.left && !node.right && cur === targetSum){
            paths.push(curPath)
        }
        buildPath(node.left, cur, curPath)
        buildPath(node.right, cur,curPath)
    }
    buildPath(root, 0, [])
    return paths
};

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

给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。

image.png

思路:

  1. 通过后序遍历的数组,找到根节点的值rootVal
  2. 通过rootVal,在中序数组中划分左子树和右子树,获得左子树的长度
  3. 分别将root.left,和root.right指向对应的中后序数组
/**
 * @param {number[]} inorder
 * @param {number[]} postorder
 * @return {TreeNode}
 */
var buildTree = function (inorder, postorder) {
    if (!inorder.length) return null
    const rootValue = postorder.pop()
    const rootIndex = inorder.findIndex(i=>i==rootValue)
    const root = new TreeNode(rootValue)
    root.left = buildTree(inorder.slice(0, rootIndex), postorder.slice(0, rootIndex))
    // 这里的postorder,因为前面已经pop出去root了,所以直接取到最后
    root.right = buildTree(inorder.slice(rootIndex + 1), postorder.slice(rootIndex))
    return root
};

105前序和中序也是一样