我用Java学算法——UVa548-Tree

一. 题目描述

https://vjudge.net/problem/UVA-548

二. 解题思路

  • 根据树的中序遍历,后序遍历构建出完整的树。后序遍历使得根节点在最后一个字符,得到根节点后,到中序遍历中找到并将树分为左右子树,再递归调用,构建出完整的树。
  • 再用DFS对树进行遍历,找出叶子节点距根节点的权重之和最小的那个叶子节点,保存最后输出该结点的权重。
  • 注意:in.hasNextLine()输出结束后要及时退出,不然总数RE!坑死我了。

三. 解题代码

import java.util.Scanner;

public class Main{

	static final int MAXV = 10000;
	static int[] inorder = new int[MAXV];
	static int[] postorder = new int[MAXV];
	static int[] lch = new int[MAXV];
	static int[] rch = new int[MAXV];

	static int bs = Integer.MAX_VALUE;
	static int n;

	public static void main(String[] args) {
		while (readLine(inorder)) {
			readLine(postorder);
			// in.close();
			builTree(0, n - 1, 0, n - 1);
			dfs(postorder[n - 1], 0);
			System.out.println(best);
			bs = Integer.MAX_VALUE;
			best = Integer.MAX_VALUE;
		}
		in.close();
	}

	private static int builTree(int il, int ir, int pl, int pr) {
		if (il > ir) {
			return 0;
		}
		int root = postorder[pr];
		int p = il;
		while (inorder[p] != root) {
			p++;
		}
		int count = p - il;
		lch[root] = builTree(il, p - 1, pl, pl + count - 1);
		rch[root] = builTree(p + 1, ir, pl + count, pr - 1);
		return root;
	}

	static int best = Integer.MAX_VALUE;

	private static void dfs(int wet, int sum) {
		sum += wet;
		if (lch[wet] == rch[wet] && rch[wet] == 0) {
			if (sum < bs || (sum == bs && wet < best)) {
				best = wet;
				bs = sum;
			}
		}
		if (lch[wet] != 0)
			dfs(lch[wet], sum);
		if (rch[wet] != 0)
			dfs(rch[wet], sum); 
	}

	static Scanner in = new Scanner(System.in);

	private static boolean readLine(int[] order) {
		if(!in.hasNextLine()){
			return false;
		}
		n = 0;
		String ns = in.nextLine();
		// System.out.println(ns);
		String[] nns = ns.split(" ");

		for (int i = 0; i < nns.length; i++) {
			order[n++] = Integer.parseInt(nns[i]);
		}

		return n > 0;
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值