代码随想录算法训练营第18天|513.找树左下角的值 ● 112. 路径总和 113.路径总和ii ● 106.从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树

513.找树左下角的值

题目链接:https://leetcode.cn/problems/find-bottom-left-tree-value/

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */
var findBottomLeftValue = function(root) {
// 最大深度和用于存储更新的最大值
let maxDepth=0,result=null
const getLeftNum=function(node,depth){
if(node.left===null&&node.right===null){
    if(depth>maxDepth){
        maxDepth=depth
        result=node.val
    }
}
if(node.left){
    depth++
    getLeftNum(node.left,depth)
    // 回溯的过程,回溯到根节点,再重新去遍历右边的节点
    depth--
}
if(node.right){
    depth++
    getLeftNum(node.right,depth)
    depth--
}
}
getLeftNum(root,1)
return result
};

解题思路:

1.题目要求的是找出最底层最左边节点的值,这里强调一点的是,最左边节点的值不一定就是左节点,假设没有左节点,那么右节点就是最左边的值,不要存在局限思维。

2.采用递归的方法和迭代法(层序遍历)都可以来解答此题,递归法相对于这道题较难理解。

3.在遍历右子树和左子树的时候,理由有回溯的思想,我有重点标注出来。

4.遍历的代码还可以优化,一行来表示,为了理解方便,这里采用冗余的代码来写更有助于理解。

112.路径总和

题目链接:https://leetcode.cn/problems/path-sum/

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @param {number} targetSum
 * @return {boolean}
 */
var hasPathSum = function(root, targetSum) {
// count为传入的目标值
const getTrackNum=function(node,count){
if(!node.left&&!node.right&&count===0) return true
if(!node.left&&!node.right) return false
if(node.left&&getTrackNum(node.left,count-node.left.val)) return true
if(node.right&&getTrackNum(node.right,count-node.right.val)) return true
return false
}
if(!root) return false
return getTrackNum(root,targetSum-root.val)
};

解题思路:

1.此题是求路径的总和,在函数的参数中传入了count参数,用来表示传入的目标值。先遍历左节点直到遍历到左节点的叶子节点,这个过程count一直做减操作,看最后遍历到叶子节点是否为0,若为0,则count再返回根节点,此过程为回溯的过程。为0,则不需要再遍历右子树,直接返回true,若不为0,返回到根节点之后再依次遍历右子树,和上述操作一样,然后再寻找符合条件的路径,若都没有,则返回false。

113.路径总和Ⅱ

题目链接:https://leetcode.cn/problems/path-sum-ii/

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @param {number} targetSum
 * @return {number[][]}
 */
var pathSum = function(root, targetSum) {
let res=[]
// 终止条件
// count为给定的值,从根节点开始递减一直到叶子节点,若为0,则说明这条路径适合。
const getNodeTrack=function(node,count,path){
    if(count===0&&!node.left&&!node.right){
        res.push([...path])
        return ;
    }
    // 遇到叶子节点没有找到合适的路径直接返回
    if(!node.left&&!node.right) return;
    // 单层递归逻辑
    if(node.left){
        path.push(node.left.val)
        getNodeTrack(node.left,count-node.left.val,path)
        path.pop() //回溯
    }
    if(node.right){
        path.push(node.right.val)
        getNodeTrack(node.right,count-node.right.val,path)
        path.pop()
    }
    return;
}
if(!root) return res
getNodeTrack(root,targetSum-root.val,[root.val]) //把根节点放进路径
return res
};

解题思路:

1.本题和上一题的解题思路大致一样,只不过本题在于要返回所有路径,上一题只要找到一个满足条件的路径就返回true,这是最大的差别

2.本题相较于上一题,多加了一个路径参数,其他的都基本没有改变。

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

题目链接:https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal/

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {number[]} inorder
 * @param {number[]} postorder
 * @return {TreeNode}
 */
var buildTree = function(inorder, postorder) {
if(!inorder.length) return null
// 从后序遍历中找出中间节点 后序:左右中
const rootVal=postorder.pop()  //后序中最后一个元素为中间节点
// 在中序遍历中凭借后序中找出来的中间节点,找出中序中中间节点所对应的位置,将左右划分出来
let rootIndex=inorder.indexOf(rootVal) //indexOf()返回指定元素在数组中所对应的下标
// 创建中间节点
const root=new TreeNode(rootVal)
// 创建左节点
root.left=buildTree(inorder.slice(0,rootIndex),postorder.slice(0,rootIndex))
// 创建右节点
root.right=buildTree(inorder.slice(rootIndex+1),postorder.slice(rootIndex))
return root
}; 

解题思路:

1.pop()方法用于删除并返回数组的最后一个元素

2.slice()方法它能基于当前数组中的一个或多个创建一个新数组。可以接受一或两个参数,即要返回的起始和结束位置。两个参数的情况下,返回起始位置和结束位置的中间数,但不包括结束位置。

3.先从后序中找出中间节点再通过找出来的中间节点去中序遍历中找出中间节点所对应的位置,然后根据中序为左中右,将左子树和右子树划分出来,之后再去后序中根据上一步寻找右子树或左子树的中间节点,以此来确定这颗二叉树。

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

题目链接:https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {number[]} preorder
 * @param {number[]} inorder
 * @return {TreeNode}
 */
var buildTree = function(preorder, inorder) {
if(!preorder.length) return null
// 在先序遍历中找出中
const rootVal=preorder.shift()  //shift用于返回数组中第一个值
// 在中序遍历中找出中间节点所处的位置,划分左右子树
const index=inorder.indexOf(rootVal)
// 创建中间节点
const root=new TreeNode(rootVal)
// 左右节点
root.left=buildTree(preorder.slice(0,index),inorder.slice(0,index))
root.right=buildTree(preorder.slice(index),inorder.slice(index+1))
return root
};

解题思路:

1.和上题思路一样。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值