leetcode刷题记录-2049. 统计最高分的节点数目

207 阅读2分钟

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

前言

今天的题目为中等,最近已经是连着两天都是数据结构相关的题目了,想要做好这种题目,首先就要去掌握基础,对于树来说,最基础的就是dfs方法了。

每日一题

今天的每日一题 2049. 统计最高分的节点数目,难度为中等

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

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

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

示例 1:

image.png

输入: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 (分别是节点 134 )。

示例 2:

image.png

输入:parents = [-1,2,0]
输出:2
解释:
- 节点 0 的分数为:2 = 2
- 节点 1 的分数为:2 = 2
- 节点 2 的分数为:1 * 1 = 1
最高分数为 2 ,有两个节点分数为 2 (分别为节点 01 )。

提示:

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

题解

dfs

重新构建树的结构数组

题目给了我们一个包含所有父节点的数组,这个数组并不是那么好看懂 parents[i] 是节点 i 的父节点 那么对于输入 [-1,2,0,2,0] 我们根据下图做一个理解

image.png

parents[i] 是节点 i 的父节点 那么 0 这个索引对应 -1,说明它是根节点,1 对应 2,那么说明它是 2 的子节点,以此类推,我们就能够得到整个的树。那么在我们看来这样的方法是能够很容易看出一个树的全貌的,但是要怎么用代码去更好地描述这棵树,这就是我们需要考虑的。

我们可以使用一个算法,来吧这个数组的结构转变为我们比较好操作的,我们可以将得到的子节点都进行转换,用一个二维数组来表示,当前节点的子节点是谁:

const children = new Array(n).fill(0);
for (let i = 0; i < n; i++) {
    children[i] = [];
}
for (let i = 0; i < n; i++) {
    const ch = parents[i];
    if (ch !== -1) {
      children[ch].push(i);
    }
}

这样是不是就能够先把题目给的数组转化为比较好理解的数组,它代表着每个位置它的子节点分别是谁。

深度优先搜索

image.png

假设我们按照题目说的去掉了某一个结点,那么剩下的部分就会是,它的右子节点,它的左子节点,和它的父节点,当然,子节点有可能是不存在的。

那么根据我们上面得到的子节点树,已经这三部分,我们可以根据深度优先搜索的递归方法,去计算每一个子树的结点值,然后返回给上一级,那么最后就可以统计最大值出现的次数。

var countHighestScoreNodes = function (parents) {
  const n = parents.length;
  let maxSco = 0;
  let res = 0;
   
  // ... 省去获得子数组方法
  
  const dfs = (elm) => {
    let sco = 1;
    let s = n - 1;
    for (const c of children[elm]) {
      let val = dfs(c);
      sco = sco * val;
      s = s - val;
    }
    if (elm !== 0) {
      sco = sco * s;
    }
    if (sco === maxSco) {
      res++;
    } else if (sco > maxSco) {
      maxSco = sco;
      res = 1;
    }
    return n - s;
  };

  dfs(0);
  return res;
};

image.png