zoukankan      html  css  js  c++  java
  • Careercup

    2014-05-08 08:26

    题目链接

    原题:

    Given a preorder traversal, create a binary search tree in optimized time

    题目:给定一个二叉搜索树的前序遍历,请重建这棵树。要求最优化算法。

    解法1:这人每次出题都要求“最优算法”,自己写的代码却实在让人汗颜,让人觉得这家伙就是懒得思考,想从别人那儿问答案。前序遍历的顺序是“根左右”,那么根节点之后所有小于根的部分就是左子树,后面就是右子树了。怎么找这条分界线呢?可以顺着找。那么算法的复杂度就是O(n * log(n))了。复杂度的证明参考归并排序即可。这个算法可行,但不是最优。

    代码:

     1 // http://www.careercup.com/question?id=5162732873580544
     2 #include <iostream>
     3 #include <vector>
     4 using namespace std;
     5 
     6 struct TreeNode {
     7     int val;
     8     TreeNode *left;
     9     TreeNode *right;
    10     TreeNode(int _val = 0): val(_val), left(nullptr), right(nullptr) {};
    11 };
    12 
    13 void constructBSTFromPreorderTraversal(vector<int> &v, int ll, int rr, TreeNode *&root)
    14 {
    15     root = new TreeNode(v[ll]);
    16 
    17     int i = ll + 1;
    18     while (i <= rr && v[i] < v[ll]) {
    19         ++i;
    20     }
    21     if (ll + 1 <= i - 1) {
    22         constructBSTFromPreorderTraversal(v, ll + 1, i - 1, root->left);
    23     }
    24     if (i <= rr) {
    25         constructBSTFromPreorderTraversal(v, i, rr, root->right);
    26     }
    27 }
    28 
    29 void inorderTraversal(TreeNode *root)
    30 {
    31     if (nullptr == root) {
    32         return;
    33     }
    34     inorderTraversal(root->left);
    35     cout << root->val << ' ';
    36     inorderTraversal(root->right);
    37 }
    38 
    39 void clearTree(TreeNode *&root)
    40 {
    41     if (nullptr == root) {
    42         return;
    43     }
    44     clearTree(root->left);
    45     clearTree(root->right);
    46     delete root;
    47     root = nullptr;
    48 }
    49 
    50 int main()
    51 {
    52     vector<int> v;
    53     int n;
    54     int i;
    55     TreeNode *root;
    56     
    57     while (cin >> n && n > 0) {
    58         v.resize(n);
    59         for (i = 0; i < n; ++i) {
    60             cin >> v[i];
    61         }
    62         root = nullptr;
    63         constructBSTFromPreorderTraversal(v, 0, n - 1, root);
    64         inorderTraversal(root);
    65         cout << endl;
    66         
    67         clearTree(root);
    68         v.clear();
    69     }
    70     
    71     return 0;
    72 }

    解法2:既然遍历是O(n)时间完成的,重建应该也可以做到O(n)。我的思路,是比较三个节点的值:父节点,当前节点,新节点。根据它们之间的大小关系可以判断新的节点应该插入在哪儿。代码中的关键部分很短,所以不需要多余解释了。其中用到了一个节点栈,用于回溯。所以这个算法用递归来写也是同样直观的。

     1 // http://www.careercup.com/question?id=5162732873580544
     2 #include <iostream>
     3 #include <vector>
     4 using namespace std;
     5 
     6 struct TreeNode {
     7     int val;
     8     TreeNode *left;
     9     TreeNode *right;
    10     TreeNode(int _val = 0): val(_val), left(nullptr), right(nullptr) {};
    11 };
    12 
    13 void inorderTraversal(TreeNode *root)
    14 {
    15     if (nullptr == root) {
    16         return;
    17     }
    18     inorderTraversal(root->left);
    19     cout << root->val << ' ';
    20     inorderTraversal(root->right);
    21 }
    22 
    23 void clearTree(TreeNode *&root)
    24 {
    25     if (nullptr == root) {
    26         return;
    27     }
    28     clearTree(root->left);
    29     clearTree(root->right);
    30     delete root;
    31     root = nullptr;
    32 }
    33 
    34 int main()
    35 {
    36     vector<int> v;
    37     int n;
    38     int i;
    39     TreeNode *root;
    40     TreeNode *tmp;
    41     vector<TreeNode *> st;
    42     
    43     while (cin >> n && n > 0) {
    44         v.resize(n);
    45         for (i = 0; i < n; ++i) {
    46             cin >> v[i];
    47         }
    48         
    49         root = new TreeNode(v[0]);
    50         st.push_back(root);
    51         for (i = 1; i < n; ++i) {
    52             if (v[i] < st[st.size() - 1]->val) {
    53                 tmp = new TreeNode(v[i]);
    54                 st[st.size() - 1]->left = tmp;
    55                 st.push_back(tmp);
    56             } else if (st.size() == 1 || v[i] < st[st.size() - 2]->val) {
    57                 tmp = new TreeNode(v[i]);
    58                 st[st.size() - 1]->right = tmp;
    59                 st.push_back(tmp);
    60             } else {
    61                 st.pop_back();
    62                 --i;
    63             }
    64         }
    65         
    66         inorderTraversal(root);
    67         cout << endl;
    68         
    69         v.clear();
    70         st.clear();
    71         clearTree(root);
    72     }
    73     
    74     return 0;
    75 }
  • 相关阅读:
    自定义异常
    java代码中正则表达式
    mybatis中代码如何实现批量添加
    List集合的三种遍历方式的效率问题
    4种方式配置不同作用域的jvm的堆栈内存!
    如何在Eclipse里修改端口
    如何用Eclipse打jar包
    用explain来解析sql语句,然后建立正确的索引
    quartz简单demo,教你最快使用quartz
    log4j.properties配置详解
  • 原文地址:https://www.cnblogs.com/zhuli19901106/p/3715359.html
Copyright © 2011-2022 走看看