Create binary tree from inorder and post order traversal - algorithm

I was trying to familarize with the question of creating a tree given inorder and postorder traversal. I wrote the following code, but some thing is going wrong which i was unable to find out. Can someone help me on this?
Sample i/p :
int in[] = {4,10,3,1,7,11,8,2};
int post[] = {4,1,3,10,11,8,2,7};
public static TreeNode buildInorderPostorder( int post[], int n, int offset,Map<Integer,Integer> indexMap,int size) {
if (size <= 0) return null;
int rootVal = post[n-1];
int i = (indexMap.get(rootVal) - offset);
TreeNode root = new TreeNode(rootVal);
root.setLeft(buildInorderPostorder( post, i, offset,indexMap,i-offset));
root.setRight(buildInorderPostorder(post, n-1, offset+i,indexMap,n-1-i));
return root;
}

root.setRight seems to be wrong.offset shouldn't be offset+i, it should be offset+i+1:
root.setRight(buildInorderPostorder(post, n-1, offset+i+1,indexMap,n-1-i));

Related

How to derive the proof of this formula for getting right child for a binary tree given inorder and preorder traversals?

I'm looking at this question on leetcode. Given two arrays, inorder and preorder, you need to construct a binary tree. I get the general solution of the question.
Preorder traversal visits root, left, and right, so the left child would be current preorder node index + 1. From that value, you can then know how many nodes are on the left of the tree using the inorder array. In the answers, the formula used to get the right child is "preStart + inIndex - inStart + 1".
I don't want to memorize the formula so I'm wondering if there is a proof for this? I went through the discussion board there, but I'm still missing a link.
For Python Only
In Python we can also use pop(0) for solving this problem, even though that's inefficient (it would pass though).
For inefficiency we can likely use deque() with popleft(), however not on LeetCode, because we don't have control over the tree.
class Solution:
def buildTree(self, preorder, inorder):
if inorder:
index = inorder.index(preorder.pop(0))
root = TreeNode(inorder[index])
root.left = self.buildTree(preorder, inorder[:index])
root.right = self.buildTree(preorder, inorder[index + 1:])
return root
For Java and C++, that'd be a bit different just like you said (don't have the proof) but maybe this post would be just a bit helpful:
public class Solution {
public static final TreeNode buildTree(
final int[] preorder,
final int[] inorder
) {
return traverse(0, 0, inorder.length - 1, preorder, inorder);
}
private static final TreeNode traverse(
final int preStart,
final int inStart,
final int atEnd,
final int[] preorder,
final int[] inorder
) {
if (preStart > preorder.length - 1 || inStart > atEnd) {
return null;
}
TreeNode root = new TreeNode(preorder[preStart]);
int inorderIndex = 0;
for (int i = inStart; i <= atEnd; i++)
if (inorder[i] == root.val) {
inorderIndex = i;
}
root.left = traverse(preStart + 1, inStart, inorderIndex - 1, preorder, inorder);
root.right = traverse(preStart + inorderIndex - inStart + 1, inorderIndex + 1, atEnd, preorder, inorder);
return root;
}
}
C++
// The following block might slightly improve the execution time;
// Can be removed;
static const auto __optimize__ = []() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
return 0;
}();
// Most of headers are already included;
// Can be removed;
#include <cstdint>
#include <vector>
#include <unordered_map>
using ValueType = int;
static const struct Solution {
TreeNode* buildTree(
std::vector<ValueType>& preorder,
std::vector<ValueType>& inorder
) {
std::unordered_map<ValueType, ValueType> inorder_indices;
for (ValueType index = 0; index < std::size(inorder); ++index) {
inorder_indices[inorder[index]] = index;
}
return build(preorder, inorder, inorder_indices, 0, 0, std::size(inorder) - 1);
}
private:
TreeNode* build(
std::vector<ValueType>& preorder,
std::vector<ValueType>& inorder,
std::unordered_map<ValueType, ValueType>& inorder_indices,
ValueType pre_start,
ValueType in_start,
ValueType in_end
) {
if (pre_start >= std::size(preorder) || in_start > in_end) {
return nullptr;
}
TreeNode* root = new TreeNode(preorder[pre_start]);
ValueType pre_index = inorder_indices[preorder[pre_start]];
root->left = build(preorder, inorder, inorder_indices, pre_start + 1, in_start, pre_index - 1);
root->right = build(preorder, inorder, inorder_indices, pre_start + 1 + pre_index - in_start, pre_index + 1, in_end);
return root;
}
};

Using Instance Variables vs Function Arguments in Recursion

Is there any difference, efficiency-wise, in using instance variables vs passing arguments by function calls during recursion? For example, I was recently doing a problem on Leetcode which asked to:
Given a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original BST is changed to the original key plus sum of all keys greater than the original key in BST.
My solution and the most popular one by far is as follows: 46 ms according to Leetcode
class Solution {
public:
int sum = 0;
TreeNode* convertBST(TreeNode* root) {
if (root == NULL) return 0;
convertBST(root->right);
sum += root->val;
root->val = sum;
convertBST(root->left);
return root;
}
};
But why couldn't we also use the following solution, or does it matter? 59 ms runtime according to Leetcode
class Solution {
public:
TreeNode* convertBST(TreeNode* root, int* sum) {
if (root == NULL) return NULL;
convertBST(root->right, sum);
*sum += root->val;
root->val = *sum;
convertBST(root->left, sum);
return root;
}
TreeNode* convertBST(TreeNode* root) {
int sum = 0;
return convertBST(root, & sum);
}
};
Thanks

Find the height of the BST tree for given array preorder representation

Example for the image above. Array representation in order is:8,3,1,6,4,7,10,14,13
I want to find out the height without constructing the Tree.....
Basically You have array representation of BST you need to find out the height of tree without constructing the tree?
This question can be solved using a recursive approach, as most tree problems are solved.
Pseudo code-
int get_height(int a[], int low, int hi) {
if(low > hi)
return -1;
int root = a[low];
// Find position pos in the range (low+1) to hi such that
// all elements at left of pos are <= root and all elements at right
// of pos are > root. Do this using modified binary search
int pos = <position for root found as described above>
int ht = 1 + max (get_height(a, low+1, pos),
get_height(a, pos+1, hi));
return ht;
}

Build binary tree from level order & inorder tree traversal

I have been preparing for an interview and came across this question:
Q. Build a binary tree from level order & inorder tree traversal.
Can someone guide me in this regard. I have been struggling with formulating the algorithm for long time now.
Here is the code I wrote:
struct node * buildLevelInTree(int * in, int * Level, int inStart, int inEnd, int level){
static int levelIndex=0;
struct node * root=newNode(Level[levelIndex++]);
//node has no child
if(inStart==inEnd)
return root;
int inIndex=searchIndex(in,inStart,inEnd,root->data);//search index of root in inorder traversal
//Note the use of level to take the next root from level order traversal
root->left=buildLevelInTree(in,Level,inStart,inIndex-1,2*level+1);
if(root->left!=NULL)
root->right=buildLevelInTree(in,Level,inIndex+1,inEnd,2*level+2);
else
root->right=buildLevelInTree(in,Level,inIndex+1,inEnd,2*level+1);
return root;
}//end of buildLevelInTree
Thanks a ton!
Finally, I could debug my code and work it out to function correctly. Next approach will be to optimise this algorithm. Suggestions to optimise this code (space wise) are welcomed.
/*
Algorithm Hint:
A
/ \
B C
/ \ / \
D E F G
inorder order will be DBEAFCG
and leve order will be ABCDEFG
From the level order, we know that A is the root, then check inorder, we further know DBE is left subtree and FCG is right subtree. to construct left subtree, from level order, we know left subtree's level order is BDE(find DBE's order in level order after A), we call the method to construct left subtree with inorder DBE and level order BDE.
*/
struct node * buildLevelInTree(int * in, int in_size, int *level, int l_size){
if(in_size==0 || l_size==0)
return NULL;
int in_index,l_count,r_count;
in_index=searchIndex(in,0,in_size,level[0]);
l_count=in_index;r_count=in_size-in_index-1;
struct node* root=newNode(level[0]);
int *in_left=makeInorder_left(in,in_size,in_index);
int *in_right=makeInorder_right(in,in_size,in_index);
int *level_left=makeLevel_left(level,l_size,in_left,l_count);
int *level_right=makeLevel_right(level,l_size,in_right,r_count);
root->left=buildLevelInTree(in_left,l_count,level_left,l_count);
root->right=buildLevelInTree(in_right,r_count,level_right,r_count);
return root;
}//end of buildLevelInTree
//Helping function for buildLevelInTree
int * makeInorder_right(int *in, int in_size, int pivot){
if(in==NULL)
return NULL;
int *in_right;
in_right=(int *)malloc(sizeof(int)*(in_size-pivot-1));
int i=pivot+1;
for(;i<in_size;i++)
in_right[i-pivot-1]=in[i];
return in_right;
}
//Helping function for buildLevelInTree
int *makeLevel_left(int *level, int lv_size, int * in_left, int inleft_size){
if(in_left == NULL || level == NULL)
return NULL;
int *level_left;
level_left=(int *)malloc(sizeof(int)*inleft_size);
int i=0;
int temp;
for(i=0;i<inleft_size;i++){
temp=searchLevel(level,lv_size,in_left[i]);
level_left[i]=temp;//searchLevel(level, lv_size, in_left[i]);
}
level_left=sort(level_left,inleft_size);
for(i=0;i<inleft_size;i++){
temp=level[level_left[i]];
level_left[i]=temp;//level[level_left[i]];
}
return level_left;
}
//Helping function for buildLevelInTree
int *makeLevel_right(int *level, int lv_size, int * in_right, int inright_size){
if(in_right == NULL || level == NULL)
return NULL;
int *level_right;
level_right=(int *)malloc(sizeof(int)*inright_size);
int i=0;
for(i=0;i<inright_size;i++)
level_right[i]=searchLevel(level, lv_size, in_right[i]);
level_right=sort(level_right,inright_size);
for(i=0;i<inright_size;i++)
level_right[i]=level[level_right[i]];
return level_right;
}
//Helping function for buildLevelInTree
int * sort(int *a,int n)
{
int i,j,k,temp;
for(i=1;i< n;i++)
{
for(j=0;j< n-1;j++)
if(a[j]>a[j+1])
{
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
return a;
}
//Helping function for buildLevelInTree
int searchLevel(int *level, int lv_size, int value){
int i=0;
for(i=0;i<lv_size;i++){
if(level[i]==value)
return i;
}
return -1;
}

Preorder to postorder in tree

I have a question i want to create postorder from inorder and preorder, but i don't wana use reconstruction of tree, i want only recursive do this. I code this, and at this moment, i have a part of, right side of tree in preorder( First char in preorder is root, i find this in inorder, and i have left and right side, i recurency translate to right side), but i have a problem with left side of tree. I don't have no idea to do this. Can someone give me some of suggestion or code ? Please help :)
public static String a(String pre, String in, int start, int end) {
char c = pre.charAt(start); //first char in preorder is root
int ix = find(pre, in, c); // if we find this char in inorder translation we know where is left and right side of tree
stack += c;
if (start == 0 && flaga == true) {
left = pre.substring(1, ix + 1);
right = pre.substring(ix + 1, end);
flaga = false;
return a(right, in, 0, end);
}
String reverse = new StringBuffer(stos).reverse().toString();
//stack to see
// System.out.println("STACK " + stos);
if (start < right.length()-1) {
return a(right, in, start + 1, end - 1);
}
return "";
}
public static int find(String a, String b, char c) {
int b_l = b.length();
for (int i = 0; i < b_l; ++i)
if (b.charAt(i) == c)
return i;
return -1;
First Test :
String pre = "FBADCEGIH";
String inorder = "ABCDEFGHI";
ANswer should be : //A, C, E, D, B, H, I, G, F
My problem is with left side of tree, i don't have any idea to do this correct, and i'm not sure my code work for all situation of preorder and inorder.

Resources