代码随想录的第十六天(二叉树)

79 阅读2分钟

代码随想录的第十六天(二叉树)

513. 找树左下角的值

层序遍历:
var findBottomLeftValue = function(root) {
    const stack = [root]
    const res = []
    while (stack.length) {
        let size = stack.length
        const arr = []
        while (size--) {
            const cur = stack.shift()
            arr.push(cur.val)
            if (cur.left) stack.push(cur.left)
            if (cur.right) stack.push(cur.right)
        }
        res.push(arr)
    }
    return res[res.length - 1][0]
};
递归法:
var findBottomLeftValue = function(root) {
    let maxDept = 0,result = null
    function getNode (node, dept) {
        if (node.left === null && node.right === null) {
            if (maxDept < dept) {
                maxDept = dept
                result = node.val
            }
        }
        if (node.left) getNode(node.left, dept+1)
        if (node.right) getNode(node.right, dept+1)
    }
    getNode(root, 1)
    return result
};
思路:

1、确定传参:根节点和一个记录最大深度的变量

2、终止条件:就是在叶子节点的时候,如果深度发生变化了就去更新返回的值,否则不更新,保证了第一进来的叶子节点肯定是最左侧的值

3、单层递归:就是左右节点依次递归就行

112. 路径总和

递归法:

var hasPathSum = function(root, targetSum) {
    function getPathSum (node, target) {
        if (target === 0 && node.left === null && node.right === null) return true
        if (target !== 0 && node.left === null && node.right === null) return false
        if (node.left && getPathSum(node.left, target - node.left.val)) return true
        if (node.right && getPathSum(node.right, target - node.right.val)) return true
        return false
    }
    if (!root) return false
    return getPathSum(root, targetSum - root.val)
};
思路:

1、确定传入的参数:根节点和目标值

2、终止条件:目标值传入后,每次都减去当前的节点的值,如果最后能等于0,说明有一条路径上的点加起来是刚好可以的,否则返回false

3、单层递归:这里首先判断节点然后去进行递归,但是如果最后的返回值是true的话,说明有一条线路是成功了,返回true即可,如果都没有匹配到,那就最后返回false

var hasPathSum = function(root, targetSum) {
    function getPathSum (node, target) {
        if (target === 0 && node.left === null && node.right === null) return true
        if (target !== 0 && node.left === null && node.right === null) return false
        if (node.left) {
            target = target - node.left.val
            if (getPathSum(node.left, target)) return true
            target = target + node.left.val
        }
        if (node.right) {
            target = target - node.right.val
            if (getPathSum(node.right, target)) return true
            target = target + node.right.val
        }
        return false
    }
    if (!root) return false
    return getPathSum(root, targetSum - root.val)
};

和上面思路一模一样,主要是为了体现下回溯算法,有递归就有回溯,后续再深入研究。

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

递归法:
var buildTree = function(inorder, postorder) {
    if (!inorder.length) return null
    const rootVal = postorder.pop()
    let rootIndex = inorder.indexOf(rootVal)
    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、传入的参数:就是传入当前的左子树的,左中序树和右中序树;右子树的左后序树和右后序树

2、首先确定终止条件:就是当最后左中序的树或者左后序的树为空的时候进行终止

2、首先根据后序获取最后一个元素为根节点,然后进行创建树;然后看中序树,节点以前的是左中序树,后序树节点以后的是右中序树,进行递归左子树;然后看后序,用得出的左中序树去切割后序的树,后序分割以后的是右子树