中级农民
- 积分
- 126
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2015-4-22
- 最后登录
- 1970-1-1
|
Max Tree
题意:Cartesian tree
解法1:首先,构造笛卡尔树的关键是找到最大点。那么就在“找到最大”上面想办法。于是想到了RMQ问题的稀疏表解法,因为数组的内容是不会变的。
代码1:- // O(log ^ 2(n)) solution, using RMQ
- /**
- * Definition of TreeNode:
- * class TreeNode {
- * public:
- * int val;
- * TreeNode *left, *right;
- * TreeNode(int val) {
- * this->val = val;
- * this->left = this->right = NULL;
- * }
- * }
- */
- class Solution {
- public:
- /**
- * @param A: Given an integer array with no duplicates.
- * @return: The root of max tree.
- */
- TreeNode* maxTree(vector<int> A) {
- int n = A.size();
- if (n == 0) {
- return NULL;
- }
-
- st.clear();
- calcSparseTable(A);
-
- return maxTreeRecur(A, 0, A.size() - 1);
- }
- private:
- // Needed for RMQ
- vector<vector<int> > st;
-
- TreeNode *maxTreeRecur(vector<int> &a, int ll, int rr) {
- if (ll > rr) {
- return NULL;
- }
- int i, mi;
-
- mi = RMQ(a, ll, rr);
- TreeNode *root = new TreeNode(a[mi]);
- root->left = maxTreeRecur(a, ll, mi - 1);
- root->right = maxTreeRecur(a, mi + 1, rr);
- return root;
- }
-
- void calcSparseTable(vector<int> &a) {
- int n = a.size();
- int b = 1;
- int m = 1;
- while (b << 1 <= n) {
- b <<= 1;
- ++m;
- }
- st.resize(m, vector<int>(n));
- int i;
- for (i = 0; i < n; ++i) {
- st[0][i] = i;
- }
- b = 1;
- int j;
- for (i = 1; i < m; ++i) {
- for (j = 0; j + (b << 1) <= n; ++j) {
- if (a[st[i - 1][j]] > a[st[i - 1][j + b]]) {
- st[i][j] = st[i - 1][j];
- } else {
- st[i][j] = st[i - 1][j + b];
- }
- }
- b <<= 1;
- }
- }
-
- int RMQ(vector<int> &a, int ll, int rr) {
- int b = 1;
- int i = 0;
- while (b << 1 <= rr - ll + 1) {
- b <<= 1;
- ++i;
- }
- if (a[st[i][ll]] > a[st[i][rr - b + 1]]) {
- return st[i][ll];
- } else {
- return st[i][rr - b + 1];
- }
- }
- };
复制代码 复杂度1:平均时间O(log^2(N)),最坏时间O(N * log(N))。空间O(N * log(N))。
解法2:这种解法我没独立想出来,参考了github其他人上的代码。思路一两句话说不清楚,利用了单调栈。感觉得多看几遍代码才能理解,很巧妙。
代码2:- // Cartesian Tree, make it O(n)
- /**
- * Definition of TreeNode:
- * class TreeNode {
- * public:
- * int val;
- * TreeNode *left, *right;
- * TreeNode(int val) {
- * this->val = val;
- * this->left = this->right = NULL;
- * }
- * }
- */
- class Solution {
- public:
- /**
- * @param A: Given an integer array with no duplicates.
- * @return: The root of max tree.
- */
- TreeNode* maxTree(vector<int> A) {
- int n = A.size();
- if (n == 0) {
- return NULL;
- }
- stack<TreeNode *> st;
- TreeNode *p, *p1, *p2;
- int i;
- for (i = 0; i < n; ++i) {
- p = new TreeNode(A[i]);
- if (!st.empty() && A[i] > st.top()->val) {
- p1 = st.top();
- st.pop();
- while (!st.empty() && A[i] > st.top()->val) {
- p2 = st.top();
- st.pop();
- p2->right = p1;
- p1 = p2;
- }
- p->left = p1;
- }
- st.push(p);
- }
-
- TreeNode *r = st.top();
- st.pop();
- while (!st.empty()) {
- st.top()->right = r;
- r = st.top();
- st.pop();
- }
- return r;
- }
- };
复制代码 复杂度2:时间O(N),空间O(N)。 |
|