Likou Solution Summary 2049 - Count the number of nodes with the highest score

Original title link: force buckle


describe:

You are given a binary tree with a root node of 0, which has a total of n nodes, and the nodes are numbered from 0 to n - 1. Also gives you a 0-based integer array parents representing the tree, where parents[i] is the parent of node i. Since node 0 is the root, parents[0] == -1 .

The size of a subtree is the number of nodes in the subtree. Each node has a score associated with it. The method to find the score of a node is to delete all the nodes and the edges connected to it, and the remaining part is several non-empty subtrees, and the score of this node is the product of the sizes of all these subtrees.

Please return the number of nodes with the highest score.

Example 1:

Input: parents = [-1,2,0,2,0]
Output: 3
Explanation:
- Node 0's score is: 3 * 1 = 3
- Node 1's score is: 4 = 4
- Node 2's score is: 1 * 1 * 2 = 2
- Node 3's score is: 4 = 4
- Node 4's score is: 4 = 4 The
highest score is 4, and there are three nodes that score 4 (nodes 1, 3, and 4).
Example 2:

Input: parents = [-1,2,0]
Output: 2
Explanation:
- Node 0's score is: 2 = 2
- Node 1's score is: 2 = 2
- Node 2's score is: 1 * 1 = 1
highest With a score of 2, there are two nodes with a score of 2 (nodes 0 and 1).
 

hint:

n == parents.length
2 <= n <= 105
parents[0] == -1
for i != 0 , there are 0 <= parents[i] <= n - 1
parents represent a binary tree.

Source: LeetCode
Link: https://leetcode-cn.com/problems/count-nodes-with-the-highest-score The
copyright belongs to Leetcode.com. For commercial reprints, please contact the official authorization, and for non-commercial reprints, please indicate the source.

Problem solving ideas:

* Problem-solving ideas: 
* The length of this question is 10^5, so the time complexity must not exceed O(NlgN), and the goal is to move closer to O(N). 
* My idea is to build a Node node one by one, each node contains the id of left, right, parent, and the number of leftNum and rightNum. 
* In the first step, we build all nodes and record them with map. It is convenient to find the node according to the id. 
* In the second step, we traverse the array, assign values ​​to the left and right of the parentNode according to the parent, and assign values ​​to the parent of the node node. 
* The third step is to recursively traverse from the root node to find the number of left nodes leftNum, the number of right nodes rightNum. If the leftNum of a node is > 0, it proves that the calculation has been done, and there is no need to repeat the calculation. In fact, there should be no scene of repeated calculation, after all, it is ordered from top to bottom. 
* The fourth step, traverse the array again. Get the corresponding node node. Since we have its leftNum, rightNum, parentNum can be calculated. Then value=leftNum*rightNum*parentNum; 
* Step 5, if value>maxvalue, then maxvaluenum=1. maxvaluenum++ if value==maxvalue. Finally return maxvaluenum

Code:

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;

    }

}

Guess you like

Origin blog.csdn.net/AA5279AA/article/details/123420565