Inorder Traversal of Cartesian Tree
Given an inorder traversal of a cartesian tree, construct the tree.
Cartesian tree : is a heap ordered binary tree, where the root is greater than all the elements in the subtree.
Note: You may assume that duplicates do not exist in the tree.
Example :
Input : [1 2 3]
Return :
3
/
2
/
1
public class Solution {
// Naive solution ->
// We know the root is the highest element in the whole array (O(N))
// Now for all the subtrees, we will be searching the biggest node
// Complexity will be O(N*Height) worst case -> (N*N), because we will be doing
// an overall search of N at every level of the tree
// Now how can we find the max element in a range ? -> SEGMENT Tree
// So using segment trees, worst case complexity will be O(NlogN)
static class SegmentTree {
// Tree stores max element & it's index
int tree[][], arr[];
SegmentTree(int[] arr) {
this.arr = arr;
int n = arr.length;
tree = new int[4 * n][];
buildTree(0, n - 1, 1);
}
public void buildTree(int start, int end, int index) {
if (start == end) {
tree[index] = new int[] { arr[start], start };
return;
}
int mid = start + (end - start) / 2;
buildTree(start, mid, 2 * index);
buildTree(mid + 1, end, 2 * index + 1);
if (tree[2 * index][0] > tree[2 * index + 1][0])
tree[index] = tree[2 * index];
else
tree[index] = tree[2 * index + 1];
}
public int findMax(int L, int R) {
int[] ans = query(0, arr.length - 1, 1, L, R);
return ans[1];
}
public int[] query(int start, int end, int index, int L, int R) {
if (start > R || end < L)
return new int[] { Integer.MIN_VALUE, -1 };
else if (start >= L && end <= R)
return tree[index];
int mid = start + (end - start) / 2;
int[] leftMax = query(start, mid, 2 * index, L, R);
int[] rightMax = query(mid + 1, end, 2 * index + 1, L, R);
if (leftMax[0] > rightMax[0])
return leftMax;
return rightMax;
}
}
SegmentTree segTree;
public TreeNode buildTree(int[] A) {
segTree = new SegmentTree(A);
return helper(A, 0, A.length - 1);
}
public TreeNode helper(int[] A, int start, int end) {
if (start > end)
return null;
// O(logN)
int rootIndex = segTree.findMax(start, end);
TreeNode root = new TreeNode(A[rootIndex]);
root.left = helper(A, start, rootIndex - 1);
root.right = helper(A, rootIndex + 1, end);
return root;
}
}
Last updated