算法竞赛入门经典 例题6-8

UVa548

Tree

给定二叉树的中序遍历和后序遍历结果,输出从根节点到叶节点的路径和最小的叶节点的值,如果有多个叶节点满足上述条件,则输出值较小的叶节点。

依次遍历后序遍历的结果,在中序遍历中查找该元素,该元素右侧的就是该节点的右子树,左侧的就是该节点的左子树。

#include <iostream>
#include <algorithm>
#include <climits>
#include <memory>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

struct Node
{
	int value;
	shared_ptr<Node> left, right;
};

class Solution
{
public:
	Solution(const vector<int> &inorder, const vector<int> &postorder)
	{
		vector<int>::const_reverse_iterator PostIter = postorder.crbegin();
		ConstructBinaryTree(tree, inorder.begin(), inorder.end(), PostIter, postorder.rend());
	}
	int GetLeafValue()
	{
		TraverseLeafNode(tree, 0);
		return LeafValue;
	}
private:
	Node tree;
	int LeastSum = INT_MAX, LeafValue;
	void ConstructBinaryTree(Node &root,
		vector<int>::const_iterator begin,
		vector<int>::const_iterator end,
		vector<int>::const_reverse_iterator &PostIter,
		vector<int>::const_reverse_iterator PostEnd)
	{
		root.value = *PostIter++;
		vector<int>::const_iterator RootIter = find(begin, end, root.value);
		if (RootIter + 1 != end) {
			root.right = make_shared<Node>();
			ConstructBinaryTree(*root.right, RootIter + 1, end, PostIter, PostEnd);
		}
		if (begin != RootIter) {
			root.left = make_shared<Node>();
			ConstructBinaryTree(*root.left, begin, RootIter, PostIter, PostEnd);
		}
	}
	void TraverseLeafNode(const Node &root, int sum)
	{
		if (root.left == nullptr && root.right == nullptr) {
			if (sum + root.value < LeastSum) {
				LeastSum = sum + root.value;
				LeafValue = root.value;
			}
			else if (sum + root.value == LeastSum) {
				LeafValue = min(LeafValue, root.value);
			}
			return;
		}
		if (root.left != nullptr) {
			TraverseLeafNode(*root.left, sum + root.value);
		}
		if (root.right != nullptr) {
			TraverseLeafNode(*root.right, sum + root.value);
		}
	}
};

vector<int> ConverseInput(const string &input)
{
	vector<int> ret;
	stringstream ss(input);
	int value;
	while (ss >> value) {
		ret.push_back(value);
	}
	return ret;
}

int main()
{
	string input;
	while (getline(cin, input)) {
		vector<int> inorder = ConverseInput(input), postorder;
		getline(cin, input);
		postorder = ConverseInput(input);
		Solution solution(inorder, postorder);
		cout << solution.GetLeafValue() << endl;
	}
	return 0;
}
/*
3 2 1 4 5 7 6
3 1 2 5 6 7 4
7 8 11 3 5 16 12 18
8 3 11 7 16 18 12 5
255
255
*/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值