算法练习day16

37 阅读2分钟

一、找树左下角的值

递归法

前序遍历,找到最大深度的叶子节点即可

/**
 * 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 result
    let maxDepth = 0
    function dfs(root, depth) {
        if(!root.left && !root.right) {
            if(depth > maxDepth) {
                maxDepth = depth
                result = root.val
                return
            }
        }
        root.left && dfs(root.left, depth + 1)
        root.right && dfs(root.right, depth + 1)
    }
    dfs(root, 1)
    return result
};

迭代法

var findBottomLeftValue = function(root) {
    let result = null
    let queue = [root]
    while(queue.length) {
        let len = queue.length
        result = queue[0].val
        for(let i = 0; i < len; i++) {
            let node = queue.shift()
            node.left && queue.push(node.left)
            node.right && queue.push(node.right)
        }
    }   
    return result 
}; 

二、路径总和

递归法

/**
 * 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) {
    function dfs(root, res) {
        if(!root) {
            return false
        }
        res -= root.val
        if(!root.left && !root.right && res === 0) {
            return true
        }
        return hasPathSum(root.left, res) || hasPathSum(root.right, res)
    }
    return dfs(root, targetSum)
};

迭代法

var hasPathSum = function(root, targetSum) {
    if(!root) {
        return false
    }
    let stack = [root]
    let valArr = [0]
    while(stack.length) {
        let node = stack.pop()
        let curVal = valArr.pop()
        curVal += node.val
        if(!node.left && !node.right && curVal === targetSum) {
            return true
        }
        if(node.right) {
            stack.push(node.right)
            valArr.push(curVal)
        }
        if(node.left) {
            stack.push(node.left)
            valArr.push(curVal)
        }
    }
    return false
};

三、路径总和2

递归法

/**
 * 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) {
    
    function dfs(root, count) {
        count -= root.val
        if(!root.left && !root.right && count === 0) {
            result.push([...path])
            return
        }
        if(root.left) {
            path.push(root.left.val)
            dfs(root.left, count)
            path.pop()
        }

        if(root.right) {
            path.push(root.right.val)
            dfs(root.right, count)
            path.pop()
        }
    }
    if(!root) {
        return []
    }
    let path = [root.val]
    let result = []
    dfs(root, targetSum)
    return result
};

迭代法

var pathSum = function(root, targetSum) {
    if(!root) {
        return []
    }
    let result = []
    let stack = [root]
    let valArr = [0]
    let pathArr = [[]]
    while(stack.length) {
        let node = stack.pop()
        let curVal = valArr.pop()
        let path = pathArr.pop()
        curVal += node.val
        path.push(node.val)
        if(!node.left && !node.right && curVal === targetSum) {
            result.push([...path])
        }
        if(node.right) {
            stack.push(node.right)
            valArr.push(curVal)
            pathArr.push([...path])
        }
        if(node.left) {
            stack.push(node.left)
            valArr.push(curVal)
            pathArr.push([...path])
        }
    }
    return result
};

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

用后序遍历和中序遍历序列构造二叉树

注意左闭右开,不变量

/**
 * @param {number[]} inorder
 * @param {number[]} postorder
 * @return {TreeNode}
 */
var buildTree = function(inorder, postorder) {
    if(!postorder.length) {
        return null
    }
    let val = postorder.pop()
    let index = inorder.indexOf(val)
    let root = new TreeNode(val)
    root.left = buildTree(inorder.slice(0, index), postorder.slice(0, index))
    root.right = buildTree(inorder.slice(index + 1), postorder.slice(index))
    return root
};

五、从中序与前序遍历序列构造二叉树

/**
 * @param {number[]} preorder
 * @param {number[]} inorder
 * @return {TreeNode}
 */
var buildTree = function(preorder, inorder) {
    if(!preorder.length) {
        return null
    }
    let val = preorder.shift()
    let index = inorder.indexOf(val)
    let root = new TreeNode(val)
    root.left = buildTree(preorder.slice(0, index), inorder.slice(0, index))
    root.right = buildTree(preorder.slice(index), inorder.slice(index+1))
    return root
};