结构和基于输入模式计算树高度。

huangapple go评论62阅读模式
英文:

Struct and Compute tree height based on an input pattern

问题

// 以下为翻译好的代码部分:

public class tree_height {

    static class FastScanner {
        StringTokenizer tok = new StringTokenizer("");
        BufferedReader in;

        FastScanner() {
            in = new BufferedReader(new InputStreamReader(System.in));
        }

        String next() throws IOException {
            while (!tok.hasMoreElements())
                tok = new StringTokenizer(in.readLine());
            return tok.nextToken();
        }

        int nextInt() throws IOException {
            return Integer.parseInt(next());
        }
    }

    public static class TreeHeight {
        int n;
        int[] parent;
        HashMap<Integer, ArrayList<Integer>> tree;

        void read() throws IOException {
            FastScanner in = new FastScanner();
            n = in.nextInt();
            parent = new int[n];
            for (int i = 0; i < n; i++) {
                parent[i] = in.nextInt();
            }
        }

        void setUpTree() {
            tree = new HashMap<>(n);
            int num;
            for (int i = 0; i < n; i++) {
                num = parent[i];
                if (num == -1)
                    tree.put(i, new ArrayList<>());
                else {
                    tree.computeIfAbsent(num, k -> new ArrayList<>());
                    tree.get(num).add(i);
                }
            }
        }

        int computeHeight() {
            setUpTree();

            // 计算树的高度
            // 在这里实现计算树的高度逻辑
        }
    }

    static public void main(String[] args) throws IOException {
        new Thread(null, new Runnable() {
            public void run() {
                try {
                    new tree_height().run();
                } catch (IOException ignored) {
                }
            }
        }, "1", 1 << 26).start();
    }

    public void run() throws IOException {
        TreeHeight tree = new TreeHeight();
        tree.read();
        System.out.println(tree.computeHeight());
    }
}

请注意,上面的翻译是给你提供了代码的整体结构和注释,但没有具体实现 computeHeight 方法中计算树高度的逻辑。如果你需要进一步实现这部分逻辑,请参考提示中的算法建议,并根据你的理解完成计算树高度的代码。

英文:

let's say I have this input

5

4 -1 4 1 1

Explanation:
The first line contains the number of nodes 𝑛. The second line contains 𝑛 integer numbers
from −1 to 𝑛 − 1 — parents of nodes. If the 𝑖-th one of them (0 ≤ 𝑖 ≤ 𝑛 − 1) is −1, node 𝑖 is the root,
otherwise, it’s 0-based index of the parent of 𝑖-th node.

0 1 2 3 4

4 -1 4 1 1

Now we can see that the node number 1 is the root because −1 corresponds to it in the second line.
Also, we know that the nodes number 3 and number 4 are children of the root node 1. Also, we know
that the nodes number 0 and number 2 are children of the node 4.

I must take this data and struct a tree. base on that input. However, I'm provided with one suggestion that I still can't fathom.

> "Suggestion: Take advantage of the fact that the labels for each tree
> node are integers in the range 0..𝑛−1: you can store each node in an
> array whose index is the label of the node. By storing the nodes in an
> array, you have 𝑂(1) access to any node given its label.
>
> allocate 𝑛𝑜𝑑𝑒𝑠[𝑛]
>
> for 𝑖 ← 0 to 𝑛 − 1:
>
> 𝑛𝑜𝑑𝑒𝑠[𝑖] =new 𝑁𝑜𝑑𝑒
>
> Then, read each parent index:
>
> for 𝑐ℎ𝑖𝑙𝑑𝑖𝑛𝑑𝑒𝑥 ← 0 to 𝑛 − 1:
>
> read 𝑝𝑎𝑟𝑒𝑛𝑡
𝑖𝑛𝑑𝑒𝑥
>
> if 𝑝𝑎𝑟𝑒𝑛𝑡𝑖𝑛𝑑𝑒𝑥 == −1:
>
> 𝑟𝑜𝑜𝑡 ← 𝑐ℎ𝑖𝑙𝑑
𝑖𝑛𝑑𝑒𝑥
>
> else:
>
> 𝑛𝑜𝑑𝑒𝑠[𝑝𝑎𝑟𝑒𝑛𝑡𝑖𝑛𝑑𝑒𝑥].𝑎𝑑𝑑𝐶ℎ𝑖𝑙𝑑(𝑛𝑜𝑑𝑒𝑠[𝑐ℎ𝑖𝑙𝑑𝑖𝑛𝑑𝑒𝑥])"

I tried to do the following:

set up a hashmap. the key is parents. and its children in an array list. since ill always be appending. the goal here is to compute the height of this tree.
In my hashmap, I have all the parents as the Key and all the children in the tree are the value which is represented as an ArrayList. the tree might not be binary therefore I might have a node with more than 2 children. if this implementation is a tree! why. why it's a tree and how could you name a tree since u don't have a Node class and the root is like any other parent. and if it is a tree. how do I even compute its height?

void setUpTree() {
tree = new HashMap&lt;&gt;(n);
int num;
for (int i = 0; i &lt; n; i++) {
num = parent[i];
if (num == -1)
tree.put(i, new ArrayList&lt;&gt;());
else {
tree.computeIfAbsent(num, k -&gt; new ArrayList&lt;&gt;());
tree.get(num).add(i);
}
}
}

the task itself is inscrutable to me since the tree is implemented using an Array. I implemented the setUpTree method based on what I understood
I have no idea if I'm on the right track. and if so. how to even compute the height. I'd appreciate any explanation or a hint.
thank you.

The complete starter code for Context:

public class tree_height {
static class FastScanner {
StringTokenizer tok = new StringTokenizer(&quot;&quot;);
BufferedReader in;
FastScanner() {
in = new BufferedReader(new InputStreamReader(System.in));
}
String next() throws IOException {
while (!tok.hasMoreElements())
tok = new StringTokenizer(in.readLine());
return tok.nextToken();
}
int nextInt() throws IOException {
return Integer.parseInt(next());
}
}
public static class TreeHeight {
int n;
int[] parent;
HashMap&lt;Integer, ArrayList&lt;Integer&gt;&gt; tree;
void read() throws IOException {
FastScanner in = new FastScanner();
n = in.nextInt();
parent = new int[n];
for (int i = 0; i &lt; n; i++) {
parent[i] = in.nextInt();
}
}
//the implementation of the algorithm provided in the suggestion
void setUpTree() {
tree = new HashMap&lt;&gt;(n);
int num;
for (int i = 0; i &lt; n; i++) {
num = parent[i];
if (num == -1)
tree.put(i, new ArrayList&lt;&gt;());
else {
tree.computeIfAbsent(num, k -&gt; new ArrayList&lt;&gt;());
tree.get(num).add(i);
}
}
}
int computeHeight() {
//set up the tree to compute its height
setUpTree();
//Compute tree height here
}
static public void main(String[] args) throws IOException {
new Thread(null, new Runnable() {
public void run() {
try {
new tree_height().run();
} catch (IOException ignored) {
}
}
}, &quot;1&quot;, 1 &lt;&lt; 26).start();
}
public void run() throws IOException {
TreeHeight tree = new TreeHeight();
tree.read();
System.out.println(tree.computeHeight());
}

答案1

得分: 1

你可以从computeHeight()函数中移除setUpTree()函数,因为在该函数中并未使用tree哈希映射。

让我们尝试计算时间复杂度。

考虑下面的树:

结构和基于输入模式计算树高度。

我们正在计算每个节点的深度,为了计算节点的深度,我们会迭代直到达到根节点。因此,对于

0,我们迭代其他节点 {}
1,我们迭代其他节点 {0}
2,我们迭代其他节点 {1, 0}
3,我们迭代其他节点 {2, 1, 0}

算法的整体时间复杂度是O(n^2)。

我们是否在做一些重复的工作?

是的,在第三次迭代中,我们知道了2的深度,而当我们计算3的时候,我们可以使用2的深度。通常情况下,我们可以说

depth[node] = 1 + depth[node->parent]

让我们使用这个来更新我们的算法。

算法

      a. 创建一个辅助数组depth,用于存储节点的深度
      b. 遍历每个节点:
          i.  如果已知节点的父节点的深度,那么
              更新 depth[node] = 1 + depth[node->parent]
          ii. 如果未知 depth[node->parent],那么
              递归计算深度,并更新路径上每个节点的深度
      c. 树的高度是所有节点中的最大深度

由于我们只访问每个节点一次,这个算法的复杂度将为O(n)。

编辑

why. why it's a tree and how could you name a tree since u don't have
a Node class and the root is like any other parent. and if it is a
tree.

有许多种实现树数据结构的方法,类似地,node 是树的一个概念,我们可以用许多方式来实现它。一种方式是使用一个 Node 类:

public class Node {
   int value;
   List<Node> children;
}

在你的情况下,我们并没有显式创建一个 Node 类,但是哈希映射条目的值看起来类似于这个 Node 类。哈希映射中的每个键表示一个节点,其值是其子节点的列表。因此,我想表达的是,有多种实现树的方式,你的方式是其中之一。你的哈希映射实现就是邻接表。在问题中,树是使用数组来表示的。

how to even compute the height
Blockquote

树的高度可以使用以下递归来计算:

height[node] = 1 + max(height[node->children])

让我们看看如何使用你给出的哈希映射表示写出这个递归:

算法

int height(HashMap map, int nodeId) {
   if (map.get(nodeId).size() == 0) {
      // 这是叶子节点
      return 0;
   }
   int maxHeightsOfSubTrees = 0;
   for (int i = 0; i < map.get(nodeId).size(); i++) {
      maxHeightsOfSubTrees = max(maxHeightsOfSubTrees, height(map, map.get(nodeId).get(i)));
   }
   return 1 + maxHeightsOfSubTrees;
}
英文:

You can remove the setUpTree() function from computeHeight() as you are not using the tree HashMap in that function.

Let's try to calculate the time complexity

Consider the following tree:

结构和基于输入模式计算树高度。

We are calculating the depth of each node and for calculating depth of a node we are iterating till we get to the top. So for

0 we iterate over other nodes {}
1 we iterate over other nodes {0}
2 we iterate over other nodes {1,0}
3 we iterate over other nodes {2,1,0}

The overall time complexity of the algorithm is O(n^2)

Are we doing some repetitive work ?

Yes, In the third iteration we know the depth of 2, and when we are doing for 3 we can use the depth of 2. In general, we can say

    depth[node] = 1 + depth[node-&gt;parent]

Lets use this to update our algorithm

Algorithm

      a. Create an auxilary array depth where we store depth of the nodes
b. Iterate over each node:
i.  If the depth of parent of node is known then 
update depth[node]=1+depth[node -&gt; parent] 
ii. If the depth[node-&gt;parent] is not known, then 
recursively calculate the depth and also update 
the depth of each node in the path
c. Height of the tree is the maximum depth among all the nodes

Since we are touching each node only once, the complexity of this algorithm will be O(n).

Edit

> why. why it's a tree and how could you name a tree since u don't have
> a Node class and the root is like any other parent. and if it is a
> tree.

There are various ways in which you can implement a tree data structure, similary node is a concept of tree and we can implement it in many ways . One way is to have a Node class

public class Node {
int value;
List&lt;Node&gt; childrens;
}

In your case we are not explicity creating a Node class, but the value of hashmap entry looks similar to this Node class. Every key in the map represent a node and its value list of its childrens. So what I want to say is that there can be multiple ways to implement a tree and yours is one of them. Your hashmap implementation is the adjacency list. In the question the tree was represented using just an array.

> how to even compute the height
> Blockquote

Height of tree can be calculated using this recursion

        heigh[node] = 1 + max( height[node-&gt;children])

Lets see how we can write it using the hashmap representation to tree you have given

Algorithm

 int  height(HashMap map, int nodeId)
if(map.get(nodeId).size() == 0)
// Its the leaf
return 0;
int maxHeightsOfSubTress = 0;
for i = 0 to map.get(nodeId).size()-1
maxHeightsOfSubTress = max(maxHeightsOfSubTress, height(map,map.get(nodeId).get(i))
return 1 + maxHeightsOfSubTress

huangapple
  • 本文由 发表于 2020年10月1日 23:49:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/64158896.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定