【题目】
将一个没有重复数字的数组中的数据构造一个二叉树
每个节点都是该子树的最大值 【要求】 时间复杂度为O(N)【题解】 使用单调栈,栈的顺序是维持从大到小排序 通过使用单调栈,将数组中中所有数的左右比他大的数记录下来 当某个数既无左边比他大的数,有无右边比他大的数,则该数为全局最大,将其作为二叉树的根 然后,某数只有左比他大的数,或者右比他大的数,则该数直接挂在比他大的数的下面, 当某个数既有左比他大的数,又有右比他大的数,则挂在两个数中较小数的下面。 然后直接构成一棵树。
1 #include2 #include 3 #include 4 #include 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 v) 17 { //以下代码都是以数组的下角标为根据 18 vector node; 19 vector >res;//存储每个数的左右大小的数 20 res.resize(v.size()); 21 deque 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 (-1, i); 32 else//有右大值和左大值 33 res[index] = pair (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 (-1, -1); 43 else//无右大值有左大值 44 res[index] = pair (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 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 }