第三波二叉树之LeetCode题

128 阅读4分钟

双递归

面试题 04.12. 求和路径

面试题 04.12. 求和路径

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @param {number} sum
 * @return {number}
 */
// 双递归
/* 
    一个主递归函数,一个内部递归函数
*/
var pathSum = function(root, sum) {
    if (root == null) return 0;
    /* 这里倒着减数字 */
    const helper = (root, sum) => {
        if (root == null) return 0;
        if (sum == root.val) {
            return 1 + helper(root.left, sum - root.val) + helper(root.right, sum - root.val);
        }
        return helper(root.left, sum - root.val) + helper(root.right, sum - root.val);
    }

    return helper(root, sum) + pathSum(root.left, sum) + pathSum(root.right, sum);
};

563. 二叉树的坡度

563. 二叉树的坡度

/**
 * 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 findTilt = function(root) {
    if (root == null) return 0;
    let res = 0;

    const dfs = (root) => {
        if (root == null) return 0;
        const left = dfs(root.left);
        const right = dfs(root.right);
        res += Math.abs(right - left);
        return right + left + root.val;
    }
    dfs(root)
    return res;
}; 

129. 求根节点到叶节点数字之和

129. 求根节点到叶节点数字之和

/**
 * 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 sumNumbers = function(root) {
    if (root == null) return 0;
    let path = [];
    const DFS = (root, sum) => {
        if (root == null) return;
        if (root.left == null && root.right == null) {
            sum = sum * 10 + root.val;
            path.push(sum);
        }
        sum = sum * 10 + root.val;
        DFS(root.left, sum);
        DFS(root.right, sum);
    }
    DFS(root, 0);
    return path.reduce((prev, next) => {
        return prev + next;
    }, 0);
};

1448. 统计二叉树中好节点的数目

1448. 统计二叉树中好节点的数目

/**
 * 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 goodNodes = function(root) {
    if (root == null) return 0;
    /* 因为根节点也是好节点 */
    let res = 0; 
    const dfs = (root, max) => {
        if (root == null) return;

        if (root.val >= max) {
            res += 1;
            max = root.val;
        }
        dfs(root.left, max);
        dfs(root.right, max);
    }
    dfs(root, Number.MIN_SAFE_INTEGER);
    return res;
};

1022. 从根到叶的二进制数之和

1022. 从根到叶的二进制数之和

/**
 * 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 sumRootToLeaf = function(root) {
    if (root == null) return 0;
    let res = 0;
    const dfs = (root, path) => {
        if (root == null) return;
        /* 添加值到路径里去 */
        path.push(root.val);
        
        if (root.left == null && root.right == null) {
            /* 处理叶子结点 */
            const num = path.join('');/* 生成二进制 */
            res += parseInt(num, 2); /* 二进制转换为10进制 */
        }
        dfs(root.left, path);
        dfs(root.right, path);
        /* 回溯 */
        path.pop();
    };
    dfs(root, [])
    return res;
};

814. 二叉树剪枝

814. 二叉树剪枝

/**
 * 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 {TreeNode}
 */
/* 利用了虚拟节点的概念 */
var pruneTree = function(root) {
    const dfs = (root) => {
        if (root == null) return 0;
        const l = dfs(root.left);
        const r = dfs(root.right);

        if (l == 0) root.left = null;
        if (r == 0) root.right = null;
        /* 加起来,如果是0 就会被剪掉 */
        return root.val + l + r;
    }
    let ans = new TreeNode(-1);
    ans.left = root;

    dfs(ans);
    return ans.left;
};

1325. 删除给定值的叶子节点

1325. 删除给定值的叶子节点

/**
 * 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} target
 * @return {TreeNode}
 */
var removeLeafNodes = function(root, target) {
    const dfs = (root) => {
        if (root == null) return null;

        root.left = dfs(root.left);
        root.right = dfs(root.right);
        /* 找到叶子节点,并且值为target */
        if (root.val == target && root.left == null && root.right == null) {
            /* 剪掉 */
            return null;
        }
        return root;
    }
    return dfs(root);

};

边界

783. 二叉搜索树节点最小距离

783. 二叉搜索树节点最小距离

/**
 * 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 minDiffInBST = function(root) {
    const dfs = (root, lower, upper) => {
        if (root == null) return upper - lower;
        const left = dfs(root.left, lower, root.val);
        const right = dfs(root.right, root.val, upper);
        return Math.min(left, right);
    }
    return dfs(root, -Infinity, Infinity);
};

1026. 节点与其祖先之间的最大差值

1026. 节点与其祖先之间的最大差值

/**
 * 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 maxAncestorDiff = function(root) {
    const dfs = (root, lower, upper) => {
        if (root == null) return upper - lower;
        /* 计算两边的差值 */
        const left = dfs(root.left, Math.min(lower, root.val), Math.max(root.val, upper));
        const right = dfs(root.right, Math.min(lower, root.val), Math.max(root.val, upper));
        /* 返回最大的一个差值 */
        return Math.max(left, right);
    }
    return dfs(root, root.val, root.val);
};

下面两个题目,是一样的

865. 具有所有最深节点的最小子树

865. 具有所有最深节点的最小子树

/**
 * 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 {TreeNode}
 */
var subtreeWithAllDeepest = function(root) {
    if (root == null) return null; 
    const getDepth = (root) => {
        if(root == null) return 0;
        return Math.max(getDepth(root.left), getDepth(root.right)) + 1;
    }
    const left = getDepth(root.left);
    const right = getDepth(root.right);

    if (left == right) {
        /* 当左右子树深度相同的时候,就是我们要找的最深的子树 */
        return root;
    } else if (left > right) {
        return subtreeWithAllDeepest(root.left);
    } else if (left < right) {
        return subtreeWithAllDeepest(root.right);
    }
};

1123. 最深叶节点的最近公共祖先

1123. 最深叶节点的最近公共祖先

/**
 * 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 {TreeNode}
 */
var lcaDeepestLeaves = function(root) {
    if (root == null) return null;
    const getDepth = (root) => {
        if (root == null) return 0;
        return Math.max(getDepth(root.left), getDepth(root.right)) + 1;
    }
    const left = getDepth(root.left);
    const right = getDepth(root.right);

    if (left == right) {
        /* 如果深度相同,那么就是我们要找的那个子树 */
        return root;
    } else if (left > right) {
        /* 左边深度高,那么就往左侧找 */
        return lcaDeepestLeaves(root.left);
    } else if (left < right) {
        /* 右边深度高,那么就往右侧找 */
        return lcaDeepestLeaves(root.right);
    }
};