Careercup - Google面试题 - 5162732873580544

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 }

 

你可能感兴趣的:(Google)