Rondom tree的高度

笔者上coursera的数据结构课时碰到了一段算法题,描述如下:
Problem Description
Task. You are given a description of a rooted tree. Your task is to compute and output its height. Recall
that the height of a (rooted) tree is the maximum depth of a node, or the maximum distance from a
leaf to the root. You are given an arbitrary tree, not necessarily a binary tree.
Input Format. 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. It is guaranteed that there is exactly one root.
It is guaranteed that the input represents a tree.
Constraints. 1 ≤ 𝑛 ≤ 105.
Output Format. Output the height of the tree.

基本的把树搭建的算法为:
allocate 𝑛𝑜𝑑𝑒𝑠[𝑛]
for 𝑖 ← 0 to 𝑛 − 1:
𝑛𝑜𝑑𝑒𝑠[𝑖] =new 𝑁𝑜𝑑𝑒
Then, read each parent index:
for 𝑐ℎ𝑖𝑙𝑑_𝑖𝑛𝑑𝑒𝑥 ← 0 to 𝑛 − 1:
read 𝑝𝑎𝑟𝑒𝑛𝑡_𝑖𝑛𝑑𝑒𝑥
if 𝑝𝑎𝑟𝑒𝑛𝑡_𝑖𝑛𝑑𝑒𝑥 == −1:
𝑟𝑜𝑜𝑡 ← 𝑐ℎ𝑖𝑙𝑑_𝑖𝑛𝑑𝑒𝑥
else:
𝑛𝑜𝑑𝑒𝑠[𝑝𝑎𝑟𝑒𝑛𝑡_𝑖𝑛𝑑𝑒𝑥].𝑎𝑑𝑑𝐶ℎ𝑖𝑙𝑑(𝑛𝑜𝑑𝑒𝑠[𝑐ℎ𝑖𝑙𝑑_𝑖𝑛𝑑𝑒𝑥])
计算树高度的方法反而并不是很值得一提,跟二叉树是一致的:
Height(tree)
if tree = nil:
return 0
return 1 + Max(Height(tree.0),Height(tree.1)…Height(tree.i))

原来的构建child关系时,使用的:

for(int j=0;j<n;j++) {
	if(Nodes[j].value==vertex) {
		Nodes[j].setParent(Nodes[vertex]);
		Nodes[vertex].Add(Nodes[j]);
	}

非常拖慢性能,导致了多次的grader失败。改为了一步到位的

else
         Nodes[Nodes[childindex].value].Add(childindex);
能快一倍左右
import java.util.*;
import java.io.*;
public class tree_height {
    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 class nodes{
 int value;
 boolean root=false;
 //ArrayList<nodes>Children;
 ArrayList<Integer> Children;
 public nodes(int value, ArrayList<Integer> Children) {
	 this.value=value;
	 this.Children=Children;
 }
 public void Add(int child) {
	this.Children.add(child);
 }
    }
   
	public class TreeHeight {
		
		int n;
		int parent[];
		
		nodes Nodes[];
		void read() throws IOException {
			FastScanner in = new FastScanner();
			n = in.nextInt();
			//ArrayList []Children=new ArrayList[n];
			ArrayList []Children=new ArrayList[n];  
		
			
			Nodes=new nodes [n];
			for (int i = 0; i < n; i++) {
				Children[i]=new ArrayList<Integer>();
				Nodes[i]=new nodes(in.nextInt(),Children[i]);	
			}
			for (int childindex = 0; childindex < n; childindex++) {
				if(Nodes[childindex].value==-1) {Nodes[childindex].root=true;
				}
				else
         Nodes[Nodes[childindex].value].Add(childindex);//这里这么写能提升很多性能
}
				}
		

		int computeHeight(nodes element) {
                        // Replace this code with a faster implementation
			int height=0;
				if(element.Children!=null) {
					int C=0; 
					for(int i=0;i<element.Children.size();i++) 
					{int temp=(int)element.Children.get(i);
						C=computeHeight(Nodes[temp]);
						if(C>height) {height=C;}
					}
					
				}	
				else
				{return 0;}
//				int height = 0;
//				for (int i = vertex; i != -1; i = parent[i])
//					height++;
//				maxHeight = Math.max(maxHeight, height);//这也是一种算法,但是效率不高
				
			
			return height+1;
		}
		int result() {
			int r=0;
			for(int i=0;i<n;i++) {
				if(Nodes[i].root) {
					r=computeHeight(Nodes[i]);
				}
				
			}
			return r;
		}
}

	static public void main(String[] args) throws IOException {
            new Thread(null, new Runnable() {
                    public void run() {
                        try {
                            new tree_height().run();
                        } catch (IOException e) {
                        }
                    }
                }, "1", 1 << 26).start();
	}
	public void run() throws IOException {
		TreeHeight tree = new TreeHeight();
		tree.read();
		System.out.println(tree.result());
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值