leetcode5:Construct Binary Tree from Preorder and Inorder Traversal

Construct Binary Tree from Preorder and Inorder Traversal

题目连接:https://oj.leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
runtimes:55ms

一、问题

Given preorder and inorder traversal of a tree, construct the binary tree.
        已经完成类似的题目:http://blog.csdn.net/shawjan/article/details/42464289

二、分析

        吸取了之前一道题最好解法的精髓,将一个大问题分解成为若干个小问题,在解决若干个小问题。
        例如:前序排列 A B D E G C F   中序排列 D B G E A C F。首先我们需要解决这个大问题,A作为树的根,那么接下来就需要解决A的左子树和右子树两个子问题,而左子树对应的前序排列 B D E G, 中序排列 D B G E,右子树对应的前序排列 C F,中序排列 C F。依次类推,我们需要解决以B为根的左子树和右子树两个小问题和以C为根的左子树和右子树的小问题。如果序列为空,则说明该小问题所在的根为空。

三、小结

        采取了递归和非递归两种方案,显然递归方案运行内存超出限制,因此改为非递归方案,但也跑了84ms之多,让我这个追求速度的汉子情何以堪。        

四、方案

递归方案的实现:
class Solution {
	
public:
	TreeNode *buildTree2(vector<int> pre, vector<int> in, int s1, int e1, int s2, int e2)
	{
		if (s2 > e2 || s1 > e1)
			return NULL;
		int i;
		for (i = s2; i <= e2; i++)
		{
			if (pre[s1] == in[i])
				break;
		}
		struct TreeNode *tree = new TreeNode(pre[s1]);
		tree->left = buildTree2(pre, in, s1 + 1, i - s2 + s1, s2, i - 1);
		tree->right = buildTree2(pre, in, e1 - e2 + i + 1, e1, i + 1, e2);
		return tree;
	}

	void outPut(TreeNode *tree)
	{
		if (tree == NULL)
			return;
		cout << tree->val << " ";
		outPut(tree->left);
		outPut(tree->right);
	}


	TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) {
		if (preorder.size() == 0 || inorder.size() == 0)
			return NULL;
		TreeNode *tree = buildTree2(preorder, inorder, 0, preorder.size() - 1, 0, inorder.size() - 1);
		outPut(tree);
		return tree;

	}
};


非递归方案的实现:
class Solution {
public:
    TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) {
        if (preorder.size() == 0 || inorder.size() == 0)
			return NULL;
		TreeNode *tree = new TreeNode(preorder[0]);
		vector <TreeNode *> treeVec;
		vector <int> paraVec;
		treeVec.push_back(tree);
		paraVec.push_back(0); paraVec.push_back(preorder.size() - 1);
		paraVec.push_back(0); paraVec.push_back(inorder.size() - 1);
		while (paraVec.size() > 0)
		{
			int s1, e1, s2, e2;
			e2 = paraVec.back(); paraVec.pop_back();
			s2 = paraVec.back(); paraVec.pop_back();
			e1 = paraVec.back(); paraVec.pop_back();
			s1 = paraVec.back(); paraVec.pop_back();
			int i;
			for (i = s2; i <= e2; i++)    //改了这里发现可以减少29ms,真是惊呆了,原来是for(<span style="font-family: Arial, Helvetica, sans-serif;">i = 0; i < inorder.size(); i++</span>)
			{
				if (preorder[s1] == inorder[i])
					break;
			}
			TreeNode *tree2 = treeVec.back(); treeVec.pop_back();
			tree2->val = preorder[s1];
			if (s1 + 1 <= i - s2 + s1 && s2 <= i - 1)
			{
				paraVec.push_back(s1 + 1); paraVec.push_back(i - s2 + s1);
				paraVec.push_back(s2); paraVec.push_back(i - 1);
				TreeNode *treeLeft = new TreeNode(0);
				tree2->left = treeLeft;
				treeVec.push_back(treeLeft);
			}
			if (e1 - e2 + i + 1 <= e1 && i + 1 <= e2)
			{
				paraVec.push_back(e1 - e2 + i + 1); paraVec.push_back(e1);
				paraVec.push_back(i + 1); paraVec.push_back(e2);
				TreeNode *TreeRight = new TreeNode(0);
				tree2->right = TreeRight;
				treeVec.push_back(TreeRight);
			}
		}
		return tree;
    }
};



五、三思

       叼!找了很久找到了一个24ms的程序,哇, 吓尿了。get到了两个新技能,一个是auto的使用,在c++98中有,用来自动判断声明变量的类型,但是极少用而且多余,后来被c++11删除了;其次是unordered_map和map的使用,酱紫会大大降低了运行时间,小伙伴都惊呆了,原来库函数的威力如此之大,以后要专研一下库函数才是。思想和我如出一则,不再赘述。

       原文链接:http://blog.xiaohuahua.org/2014/12/17/leetcode-construct-binary-tree-from-preorder-and-inorder-traversal/



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值