力扣解法汇总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 表示一棵二叉树。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/count-nodes-with-the-highest-score
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

* 解题思路:
* 这题长度10^5,那么时间复杂度一定不能超过O(NlgN),目标还是往O(N)靠拢。
* 我的想法是构建一个一个的Node节点,每个节点包含left,right,parent的id,以及leftNum和rightNum的数量。
* 第一步,我们构建所有的节点,用map记录。方便根据id查找该节点。
* 第二步,我们遍历数组,根据parent分别给parentNode的left和right赋值,以及给node节点的parent赋值。
* 第三步,从根节点开始递归遍历,找到left的节点数量leftNum,right的节点数量rightNum.如果某个节点的leftNum>0,则证明计算过,无需重复计算。其实应该也不会出现重复计算的场景,毕竟是从上向下有序的。
* 第四步,再次遍历数组。获取对应的node节点。因为我们有其leftNum,rightNum,则可以计算出parentNum。则value=leftNum*rightNum*parentNum;
* 第五步,如果value>maxvalue,则maxvaluenum=1。如果value==maxvalue,则maxvaluenum++。最终返回maxvaluenum即可

代码:

public class Solution2049 {

    public int countHighestScoreNodes(int[] parents) {
        Map<Integer, Node> map = new HashMap<>();//1,2
        for (int i = 0; i < parents.length; i++) {
            Node node = new Node();
            node.value = i;
            map.put(i, node);
        }
        for (int i = 0; i < parents.length; i++) {
            int parent = parents[i];
            Node parentNode = map.get(parent);
            if (parentNode == null) {
                continue;
            }
            if (parentNode.left == -1) {
                parentNode.left = i;
                continue;
            }
            parentNode.right = i;

            Node node = map.get(i);
            node.parent = parent;
        }
        int num = searchList(map.get(0), map);
        long maxValue = 0;
        int maxValueNum = 0;
        for (int i = 0; i < parents.length; i++) {
            Node node = map.get(i);
            long leftNum = node.leftNum;
            long rightNum = node.rightNum;
            long topNum = num - leftNum - rightNum - 1;
            topNum = topNum == 0 ? 1 : topNum;
            leftNum = leftNum == 0 ? 1 : leftNum;
            rightNum = rightNum == 0 ? 1 : rightNum;
            long value = leftNum * rightNum * topNum;
            if (value > maxValue) {
                maxValueNum = 1;
                maxValue = value;
            } else if (value == maxValue) {
                maxValueNum++;
            }
        }
        return maxValueNum;
    }

    private int searchList(Node node, Map<Integer, Node> map) {
        int leftNum = 0;
        int rightNum = 0;
        if (node.left >= 0) {
            if (node.leftNum > 0) {
                leftNum = node.leftNum;
            } else {
                leftNum = searchList(map.get(node.left), map);
            }
        }
        if (node.right >= 0) {
            if (node.rightNum > 0) {
                rightNum = node.rightNum;
            } else {
                rightNum = searchList(map.get(node.right), map);
            }
        }
        node.leftNum = leftNum;
        node.rightNum = rightNum;
        return leftNum + rightNum + 1;
    }


    static class Node {
        int value = -1;
        int leftNum = 0;
        int rightNum = 0;
        int parent = -1;
        int left = -1;
        int right = -1;

    }

}

猜你喜欢

转载自blog.csdn.net/AA5279AA/article/details/123420565
今日推荐