第二波二叉树的LeetCode

348 阅读2分钟

94. 二叉树的中序遍历

94. 二叉树的中序遍历

/**
 * 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 inorderTraversal = function(root) {
    const res = []
    function inorder(node) {
        if (node == null) return;

        inorder(node.left);

        if (node.val) {
            res.push(node.val);
        }

        inorder(node.right);
    }
    inorder(root);
    return res;
};

173. 二叉搜索树迭代器

173. 二叉搜索树迭代器

算法思路:

  1. 在构造器里面的时候,使用中序遍历,都把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
 */
var BSTIterator = function(root) {
    this.arr = [];
    this.index = 0;
    this.inorder(root);
};
/**
 * @return {number}
 */
BSTIterator.prototype.next = function() {
    return this.arr[this.index++];
};
/**
 * @return {boolean}
 */
BSTIterator.prototype.hasNext = function() {
    return this.index < this.arr.length;
};
/* 中序遍历 */
BSTIterator.prototype.inorder = function(node) {
    if (node == null) return;
    this.inorder(node.left);
    //zhu 
    if (node.val !== null) {
        this.arr.push(node.val);
    }
    this.inorder(node.right);
};
/**
 * Your BSTIterator object will be instantiated and called as such:
 * var obj = new BSTIterator(root)
 * var param_1 = obj.next()
 * var param_2 = obj.hasNext()
 */

完全二叉树

222. 完全二叉树的节点个数

222. 完全二叉树的节点个数

使用的BFS 广度优先遍历,来计算数量

/**
 * 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 == null) return 0;
    let arr = [root];
    let res = 1;
    while (arr.length) {
        let node = arr.shift();
        if (node.left) {
            res++;
            arr.push(node.left);
        }
        if (node.right) {
            res++;
            arr.push(node.right);
        }
    }
    return res;
};

662. 二叉树最大宽度

662. 二叉树最大宽度

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

    let res = 0;
    let leftmost = 0;
    let cur_deps = 0;
    let steps = 0;

    let queue = [[root, 0]];
    while (queue.length) {
        const len = queue.length;

        for(let i = 0; i < len; i++) {
            let [node, pos] = queue.shift();

            if (node || node.val == 0) {
                queue.push([node.left, pos * 2]);
                queue.push([node.right, pos * 2 + 1]);
                if (cur_deps !== steps) {
                    cur_deps = steps;
                    leftmost = pos;
                }
                res = Math.max(res, pos - leftmost + 1);
            }
        }
        steps += 1;
    }
    return res;
};

919. 完全二叉树插入器

919. 完全二叉树插入器

/**
 * 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
 */
var CBTInserter = function(root) {

};

/** 
 * @param {number} val
 * @return {number}
 */
CBTInserter.prototype.insert = function(val) {

};

/**
 * @return {TreeNode}
 */
CBTInserter.prototype.get_root = function() {

};

/**
 * Your CBTInserter object will be instantiated and called as such:
 * var obj = new CBTInserter(root)
 * var param_1 = obj.insert(val)
 * var param_2 = obj.get_root()
 */

路径

124. 二叉树中的最大路径和

124. 二叉树中的最大路径和

/**
 * 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}
 */
// DFS 后序遍历
var maxPathSum = function(root) {
    if (root == null) return 0;
    let res = Number.MIN_SAFE_INTEGER;
    const dfs = (node, val) => {
        if (node == null) return 0;
        
        const left = dfs(node.left);
        const right = dfs(node.right);
        /* 所有的路径加起来 */
        const maxSum = left + node.val + right;
        /* 获取最大值,也是最终的返回值 */
        res = Math.max(maxSum, res);
        /* 当前子树,能够对外提供的最大的值 */
        let outputSum = node.val + Math.max(0, left, right);
        return outputSum < 0 ? 0 : outputSum;
    }
    dfs(root);
    return res;
};

113. 路径总和 II

113. 路径总和 II

路径的概念是:一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。这听起来真的不容易理解,力扣给的 demo 我也没搞懂,这里我自己画了几个图来给大家解释一下这个概念。

/**
 * 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[][]}
 */
// DFS + 回溯
var pathSum = function(root, targetSum) {
    if (root == null) return [];
    let res = [];
    let path = [];
    // DFS 
    const dfs = (node, sum, path) => {
        /* 第一步肯定是要终止条件 */
        if (node == null) return;
        /* 添加路径 */
        path.push(node.val);
        /* 开始加数, 计算路径总和 */
        sum += node.val;
        // 先条件判断,找到叶子节点
        if (node.left == null && node.right == null) {
            if (targetSum == sum) {
                res.push([...path]);
            }
        }
        if (node.left) {
            dfs(node.left, sum, path);
        }
        if (node.right) {
            dfs(node.right, sum, path);
        }
        // 回溯
        path.pop();
    };
    dfs(root, 0, path);
    return res;
};

距离

863. 二叉树中所有距离为 K 的结点

863. 二叉树中所有距离为 K 的结点

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @param {TreeNode} target
 * @param {number} k
 * @return {number[]}
 */
var distanceK = function(root, target, k) {
    const map = new Map();
    const res = [];

    /* map 记录所有节点的父节点, 目的就是为了能向自己的父元素去递归查找 */
    function findParents(node) {
        if (node.left) {
            map.set(node.left.val, node);
            findParents(node.left);
        }
        if (node.right) {
            map.set(node.right.val, node);
            findParents(node.right);
        }
    }
    findParents(root);

    function DFS (node, from, depth, k) {
        if (!node) return;
        if (depth === k) {
            res.push(node.val);
            return;
        }
        // 向左下边递归
        if (node.left !== from) {
            DFS(node.left, node, depth + 1, k);
        }
        /* 向右下边递归 */
        if (node.right !== from) {
            DFS(node.right, node, depth + 1, k);
        }
        /* 向父元素递归 */
        if (map.get(node.val) !== from) {
            DFS(map.get(node.val), node, depth + 1, k);
        }
    }
    DFS(target, null, 0, k);
    return res;
};

834. 树中距离之和

834. 树中距离之和

这个暂时占个坑

/**
 * @param {number} n
 * @param {number[][]} edges
 * @return {number[]}
 */
let ans, sz, dp, graph;
const dfs = (u, f) => {
    sz[u] = 1;
    dp[u] = 0;
    for (const v of graph[u]) {
        if (v === f) {
            continue;
        }
        dfs(v, u);
        dp[u] += dp[v] + sz[v];
        sz[u] += sz[v];
    }
}
const dfs2 = (u, f) => {
    ans[u] = dp[u];
    for (const v of graph[u]) {
        if (v === f) {
            continue;
        }
        const pu = dp[u], pv = dp[v];
        const su = sz[u], sv = sz[v];

        dp[u] -= dp[v] + sz[v];
        sz[u] -= sz[v];
        dp[v] += dp[u] + sz[u];
        sz[v] += sz[u];

        dfs2(v, u);

        dp[u] = pu, dp[v] = pv;
        sz[u] = su, sz[v] = sv;
    }
}
var sumOfDistancesInTree = function(n, edges) {
    ans = new Array(n).fill(0);
    sz = new Array(n).fill(0);
    dp = new Array(n).fill(0);
    graph = new Array(n).fill(0).map(v => []);
    for (const [u, v] of edges) {
        graph[u].push(v);
        graph[v].push(u);
    }
    dfs(0, -1);
    dfs2(0, -1);
    return ans;
};