leetcode5:Construct Binary Tree from Preorder and Inorder Traversal

来源:互联网 发布:linux vi创建文件 编辑:程序博客网 时间:2024/06/03 17:53

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/



0 0
原创粉丝点击