开启我的LeetCode刷题日记:2049. 统计最高分的节点数目

118 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

编程世界总是离不了算法

最近在看框架源码时,会有很多算法的实现逻辑,有时候会感到吃力

于是决定蹭着假期,加强算法和数据结构相关的知识

那怎么提升呢?

其实我知道算法这东西没有捷径,多写多练才能提升,于是我开启我的LeetCode刷题之旅

第一阶段目标是:200道,每天12

为了不乱,本系列文章目录分为三部分:

  1. 今日题目:xxx
  2. 我的思路
  3. 代码实现

今天题目:2049. 统计最高分的节点数目

给你一棵根节点为 0 的 二叉树 ,它总共有 n 个节点,节点编号为 0 到 n - 1 。同时给你一个下标从 0 开始的整数数组 parents 表示这棵树,其中 parents[i] 是节点 i 的父节点。由于节点 0 是根,所以 parents[0] == -1 。

一个子树的 大小 为这个子树内节点的数目。每个节点都有一个与之关联的 分数 。求出某个节点分数的方法是,将这个节点和与它相连的边全部 删除 ,剩余部分是若干个 非空 子树,这个节点的 分数 为所有这些子树 大小的乘积 。

请你返回有 最高得分 节点的 数目 。

 

示例 1:

输入:parents = [-1,2,0,2,0] 输出:3 解释:

  • 节点 0 的分数为:3 * 1 = 3
  • 节点 1 的分数为:4 = 4
  • 节点 2 的分数为:1 * 1 * 2 = 2
  • 节点 3 的分数为:4 = 4
  • 节点 4 的分数为:4 = 4 最高得分为 4 ,有三个节点得分为 4 (分别是节点 1,3 和 4 )。 示例 2:

输入:parents = [-1,2,0] 输出:2 解释:

  • 节点 0 的分数为:2 = 2
  • 节点 1 的分数为:2 = 2
  • 节点 2 的分数为:1 * 1 = 1 最高分数为 2 ,有两个节点分数为 2 (分别为节点 0 和 1 )。  

提示:

n == parents.length 2 <= n <= 105 parents[0] == -1 对于 i != 0 ,有 0 <= parents[i] <= n - 1 parents 表示一棵二叉树。

我的思路

1、首先构造二叉树,这里参考了一个大佬的方法,自己原来用递归效率会低很多。 2、用后序遍历对构造好的树进行遍历,并记录下每个节点本身及其所有子节点的个数(nodeCount) 3、然后对每个点分别进行删除点,取其左、右、剩余节点个数取乘积,比较每次结果即可得出结果

代码实现

/**
 * @param {number[]} parents
 * @return {number}
 */
var countHighestScoreNodes = function (parents) {
    let treeArr = parents.map((i, idx) => new Tree(idx)), total = parents.length, val = 0, count = 0
    for (let i = 0; i < total; i++) {
        if (treeArr[parents[i]])
            treeArr[parents[i]].addChild(treeArr[i])
    }
    /****** 以上为构造树,treeArr[0]为根节点 *****/

    getTreeNodeCount(treeArr[0]) // 对树进行后序遍历,并记录下每个节点及其子节点的节点个数

    for (let i = 0; i < total; i++) { // 对每个点分别进行删除点,取其左、右、剩余节点个数取乘积,比较每次结果
        let left = treeArr[i]?.left?.nodeCount || 0
        let right =treeArr[i]?.right?.nodeCount || 0
        let cur = total - left - right - 1
        let newVal = (cur || 1) * (left || 1) * (right || 1)
        if(newVal === val) count ++
        if(newVal > val) {
            val = newVal
            count = 1
        }
    }
    return count
};

/**
 * @param {number} val
 * @param {Tree} left
 * @param {Tree} right
 */
class Tree {
    constructor(val, left = null, right = null) {
        this.val = val
        this.left = left
        this.right = right
        this.nodeCount = 1
    }

    /**
    * @param {Tree} node
    */
    addChild(node) {
        if (this.left) {
            this.right = node
        } else {
            this.left = node
        }
    }
    addNodeCount(count) {
        this.nodeCount = this.nodeCount + count
    }
}
/**
 * @param {Tree} tree
 */
function getTreeNodeCount(tree) {
    if (tree.left) getTreeNodeCount(tree.left)
    if (tree.right) getTreeNodeCount(tree.right)
    if(tree.left?.nodeCount) tree.addNodeCount(tree.left.nodeCount)
    if(tree.right?.nodeCount) tree.addNodeCount(tree.right.nodeCount)
}

总结

实现方式其实有很多,这里仅供参考~

由于刚开始刷题,也不知道从哪里刷好,如果前辈们有好的建议,希望不吝赐教,感谢🌹