算法练习day14

69 阅读2分钟

递归法三步走

  1. 确定递归函数的参数和返回值

  2. 确定终止条件

  3. 确定单层递归的逻辑

一些概念

二叉树节点的深度

从根节点到该节点的最长简单路径边的条数或节点数

二叉树节点的高度

从该节点到叶子节点的最长简单路径边的条数或节点数

根节点的高度就是二叉树的最大深度

一、二叉树的最大深度

递归法, 后序遍历

/**
 * 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 maxDepth = function(root) {
    if(!root) {
        return 0
    }
    return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1
};

递归法,前序遍历

var maxDepth = function(root) {
    let result = 0
    function getDepth(root, depth) {
        result = Math.max(result, depth)
        if(root.left) {
            getDepth(root.left, depth + 1)
        }
        if(root.right) {
            getDepth(root.right, depth + 1)
        }
    }
    
    if(!root) {
        return result
    }
    getDepth(root, 1)
    return result
};

N叉树的最大深度

var maxDepth = function(root) {
    if(!root) return 0
    let depth = 0
    for(let node of root.children) {
        depth = Math.max(depth, maxDepth(node))
    }
    return depth + 1
}

二、二叉树的最小深度

本题中最小深度是从根节点到最近叶子节点的最短路径上的节点数量,所以要注意判断递归的终止条件

/**
 * 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 minDepth = function(root) {
    if(!root) {
        return 0
    }
    if(!root.left && !root.right) {
        return 1
    }
    if(!root.left) {
        return minDepth(root.right) + 1
    }
    if(!root.right) {
        return minDepth(root.left) + 1
    }
    return Math.min(minDepth(root.right), minDepth(root.left)) + 1
};

三、完全二叉树的节点个数

递归法,后序

/**
 * 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 countNodes = function(root) {
    if(!root) {
        return 0
    }
    let leftCount = countNodes(root.left)
    let rightCount = countNodes(root.right)
    return leftCount + rightCount + 1

};

层序遍历法

var countNodes = function(root) {
    if(!root) {
        return 0
    }
    let count = 0
    let queue = [root]
    while(queue.length) {
        let len = queue.length
        for(let i = 0; i < len; i++) {
            count++
            let node = queue.pop()
            node.left && queue.push(node.left)
            node.right && queue.push(node.right)
        }
    }
    return count

};

利用完全二叉树性质

var countNodes = function(root) {
    if(!root) {
        return 0
    }
    let left = root.left
    let right = root.right
    let leftDepth = 1
    let rightDepth = 1
    while(left) {
        leftDepth++
        left = left.left
    }
    while(right) {
        rightDepth++
        right = right.right
    }
    if(leftDepth === rightDepth) {
        return Math.pow(2, leftDepth) - 1
    }

    return countNodes(root.left) + countNodes(root.right) + 1
};