【题目】
将一个没有重复数字的数组中的数据构造一个二叉树
每个节点都是该子树的最大值
【要求】
时间复杂度为O(N)
【题解】
使用单调栈,栈的顺序是维持从大到小排序
通过使用单调栈,将数组中中所有数的左右比他大的数记录下来
当某个数既无左边比他大的数,有无右边比他大的数,则该数为全局最大,将其作为二叉树的根
然后,某数只有左比他大的数,或者右比他大的数,则该数直接挂在比他大的数的下面,
当某个数既有左比他大的数,又有右比他大的数,则挂在两个数中较小数的下面。
然后直接构成一棵树。
1 #include <iostream> 2 #include <vector> 3 #include <deque> 4 #include <sstream> 5 6 using namespace std; 7 8 struct Node 9 { 10 int val; 11 Node* lchild; 12 Node* rchild; 13 Node(int a) :val(a), lchild(nullptr), rchild(nullptr) {} 14 }; 15 16 void creatMaxTree(Node*& root, vector<int>v) 17 {//以下代码都是以数组的下角标为根据 18 vector<Node*>node; 19 vector<pair<int, int>>res;//存储每个数的左右大小的数 20 res.resize(v.size()); 21 deque<int>d;//单调栈 22 for (int i = 0; i < v.size(); ++i) 23 { 24 Node* p = new Node(v[i]); 25 node.push_back(p);//先生成相关的节点 26 while (!d.empty() && v[i] > v[d.back()]) 27 { 28 int index = d.back(); 29 d.pop_back(); 30 if (d.empty())//有右大值,无左大值 31 res[index] = pair<int, int>(-1, i); 32 else//有右大值和左大值 33 res[index] = pair<int, int>(d.back(), i); 34 } 35 d.push_back(i); 36 } 37 while (!d.empty()) 38 { 39 int index = d.back(); 40 d.pop_back(); 41 if (d.empty())//即无右大值,又无左大值 42 res[index] = pair<int, int>(-1, -1); 43 else//无右大值有左大值 44 res[index] = pair<int, int>(d.back(), -1); 45 } 46 for (int i = 0; i < res.size(); ++i) 47 { 48 int a, b; 49 a = res[i].first; 50 b = res[i].second; 51 if (a == -1 && b == -1)//即无右大值,又无左大值为根节点 52 root = node[i]; 53 else if (a == -1 && b != -1) 54 node[b]->rchild = node[i]; 55 else if (a != -1 && b == -1) 56 node[a]->lchild = node[i]; 57 else if (v[a] > v[b]) 58 node[b]->rchild = node[i]; 59 else 60 node[a]->lchild = node[i]; 61 } 62 } 63 64 //打印树形状进行查看 65 class PrintTree 66 { 67 public: 68 void Print(Node* root) 69 { 70 cout << "The shape of tree is: " << endl; 71 cout << "=============================================================" << endl; 72 PrintShape(root, 0, "H", 17); 73 cout << "=============================================================" << endl; 74 } 75 void PrintShape(Node* root, int h, string c, int len) 76 { 77 if (root) 78 { 79 PrintShape(root->rchild, h + 1, "v", len); 80 string val; 81 stringstream ss; 82 ss << root->val; 83 ss >> val; 84 val = c + val + c; 85 int lenM = val.length(); 86 int lenL = (len - lenM) / 2; 87 int lenR = len - lenM - lenL; 88 val = getSpace(lenL) + val + getSpace(lenR); 89 cout << getSpace(h*len) + val << endl; 90 PrintShape(root->lchild, h + 1, "^", len); 91 } 92 93 } 94 string getSpace(int num) 95 { 96 string space = " "; 97 for (int i = 0; i < num; ++i) 98 space.append(" "); 99 return space; 100 } 101 }; 102 103 void Test() 104 { 105 vector<int>v; 106 v = { 5,3,4,2,6,1 }; 107 Node* root = nullptr; 108 creatMaxTree(root, v); 109 PrintTree print; 110 print.Print(root); 111 }