I have written the program to convert a sorted array into a bst but when I run inorder on it it only returns one value,
static Node insert(int[] arr, int lo, int hi){
if(lo>hi){
return null;
}
int mid = lo + (hi - lo)/2;
root = new Node(arr[mid]);
root.left = insert(arr, lo, mid-1);
root.right = insert(arr, mid+1, hi);
return root;
}
inOrder(insert(nodes, 0, nodes.length-1)); - return only 87, inorder is the regular recursive function.
the array int[] nodes = {12, 25, 37, 50, 62, 75, 87};
root = new Node(arr[mid]); // wrong
You should declare root pointer at local scope. Currently you just modify the one declared at outer scope and end up returning that at the ending.
Change to:
Node root = new Node(arr[mid]);
Related
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;
}
};
For example, given the following binary tree:
[2,3,5,4,8,6,-2,null,null,null,null,null,null,null,2] and sum = 7
2
/ \
3 5
/ \ / \
4 8 6 -2
\
2
Print : [3,4] , [2,5] , [2,5,-2,2]
I could come up with a n^2 solution, but is there a better solution to it? Maybe with a some extra memory, like using a stack or hashtable.
I've spent 4 hours trying to come up with some solution, but all the solution becomes too ugly or chaotic.
My n^2 solution is relatively simple:
1) Have one method i.e. helper which recursively calls itself till all the leafs. When it finds a path with the sum, add it to the result. (This is will take O(n))
2)Call this method for every node in the tree ( O(n) * O(n) = O(n^2))
My simple solution
//TreeNode structure
public class TreeNode {
int val;
public TreeNode left;
public TreeNode right;
TreeNode(int x) { val = x; }
}
//Solution class
public class Solution {
public List<List<Integer>> pathSum(TreeNode root, int sum) {
List<Integer> temp = new ArrayList<Integer>();
List<List<Integer>> result = new ArrayList<>();
if (root == null) return result;
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
while ( !q.isEmpty())
{
TreeNode top = q.poll();
helper(top,sum,temp,result);
if (top.left != null) q.offer(top.left);
if (top.right != null) q.offer(top.right);
}
return result;
}
public void helper(TreeNode root, int sum, List<Integer> temp, List<List<Integer>> result)
{
if (root == null) return;
temp.add(root.val) ;
if (root.val == sum)
{
result.add(new ArrayList<>(temp));
}
helper(root.left,sum-root.val, temp, result );
helper(root.right, sum-root.val, temp, result);
temp.remove(temp.size() - 1);
}
}
//Execution class
public class treeApp {
public static void main(String args[])
{ TreeNode root = new TreeNode(2);
root.left = new TreeNode(3);
root.right = new TreeNode(5);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(8);
root.right.left = new TreeNode(6);
root.right.right = new TreeNode(-2);
root.right.right.right = new TreeNode(2);
Solution sol = new Solution();
List<List<Integer>> result ;
result = sol.pathSum(root, 7);
for (List l : result)
{
System.out.println(l.toString());
}
}
//Prints:
[2, 5]
[2, 5, -2, 2]
[3, 4]
Traverse the tree in any convenient fashion (breadth-first or depth-first), but include the path to this node.
At each node, check all of the path sums that end at this node; if any equal the target value, add those paths to the solution (passed back as the functional result).
Then recur: add the current node to the path and call on each child.
Is this clear enough? I think this solves the problem in less time. The traversal is O(N) to reach all the nodes. At each node, you walk through the path, which is of length . If you have a balanced binary tree, the depth is O(log2[N]).
So I've successfully implemented a quicksort that uses the leftmost element as the pivot every time. I've been trying to implement quicksort using the middle element and having some complicated results. I have been working off of examples that has quicksort recursively call itself without wrapping the calls in any sort of condition and, as you might imagine, it gets stuck on the first call to itself.
The first calls to partition with the samples I've used partition the array correctly, then as it approaches the end, just swaps the two of the elements at the beginning over and over again.
The strategy that I am attempting is to pick the middle element from the list as the pivot, stow it away at the end of the array and then proceed to swap indices. After that pass it complete, I put the pivot between the partitioned arrays. Looks good after a couple of passes, but as I mentioned, gets stuck early on and never gets to the call that should sort the second partition.
any nudges would be greatly appreciated - I also was working in groovy, if you see anything off (and hopefully that isn't causing any issues, but I avoided duck typing for this
the original array is
[100, 305, 2, 2002, 18, 99, 211, 30, 50, 1000, 403, 4, 400, 77]
and when stack overflow is reached the array is
[2, 4, 18, 30, 50, 99, 77, 100, 211, 1000, 403, 305, 400, 2002]
class OtherQuickSort {
static void sort(int[] array){
quickSort(array, 0, array.length - 1)
}
static void quickSort(int[] array, int first, int last){
int pivotIndex = partition(array, first, last)
quickSort(array, first, pivotIndex - 1)
quickSort(array, pivotIndex, last)
}
static int partition(int[] array, int first, int last){
int pivotIndex = (first + last) / 2
int pivotValue = array[pivotIndex]
swapIndices(array, pivotIndex, last)
int indexFromRight = last - 1
int indexFromLeft = first
while(indexFromLeft <= indexFromRight){
while(array[indexFromLeft] < pivotValue){
indexFromLeft++
}
while(array[indexFromRight] > pivotValue){
indexFromRight--
}
if(indexFromLeft <= indexFromRight) {
swapIndices(array, indexFromLeft, indexFromRight)
indexFromLeft++
indexFromRight--
}
}
swapIndices(array, indexFromLeft, last)
indexFromLeft
}
static void swapIndices(int[] array, int left, int right){
int leftValue = array[left]
array[left] = array[right]
array[right] = leftValue
}
}
You need to update your quickSort method. Value at the pivotIndex is already in its sorted position so you need not pass it again.
static void quickSort(int[] array, int first, int last){
if(last > first){
int pivotIndex = partition(array, first, last);
quickSort(array, first, pivotIndex-1);
quickSort(array, pivotIndex+1, last);
}
}
How to construct a binary tree using a level order traversal sequence, for example from sequence {1,2,3,#,#,4,#,#,5}, we can construct a binary tree like this:
1
/ \
2 3
/
4
\
5
where '#' signifies a path terminator where no node exists below.
Finally I implement Pham Trung's algorithm by c++
struct TreeNode
{
TreeNode *left;
TreeNode *right;
int val;
TreeNode(int x): left(NULL), right(NULL), val(x) {}
};
TreeNode *build_tree(char nodes[], int n)
{
TreeNode *root = new TreeNode(nodes[0] - '0');
queue<TreeNode*> q;
bool is_left = true;
TreeNode *cur = NULL;
q.push(root);
for (int i = 1; i < n; i++) {
TreeNode *node = NULL;
if (nodes[i] != '#') {
node = new TreeNode(nodes[i] - '0');
q.push(node);
}
if (is_left) {
cur = q.front();
q.pop();
cur->left = node;
is_left = false;
} else {
cur->right = node;
is_left = true;
}
}
return root;
}
Assume using array int[]data with 0-based index, we have a simple function to get children:
Left child
int getLeftChild(int index){
if(index*2 + 1 >= data.length)
return -1;// -1 Means out of bound
return data[(index*2) + 1];
}
Right child
int getRightChild(int index){
if(index*2 + 2 >= data.length)
return -1;// -1 Means out of bound
return data[(index*2) + 2];
}
Edit:
Ok, so by maintaining a queue, we can build this binary tree.
We use a queue to maintain those nodes that are not yet processed.
Using a variable count to keep track of the number of children added for the current node.
First, create a root node, assign it as the current node.
So starting from index 1 (index 0 is the root), as the count is 0, we add this node as left child of the current node.
Increase count. If this node is not '#', add it to the queue.
Moving to the next index, the count is 1, so we add this as right child of current node, reset count to 0 and update current node (by assigning the current node as the first element in the queue). If this node is not '#', add it to the queue.
int count = 0;
Queue q = new Queue();
q.add(new Node(data[0]);
Node cur = null;
for(int i = 1; i < data.length; i++){
Node node = new Node(data[i]);
if(count == 0){
cur = q.dequeue();
}
if(count==0){
count++;
cur.leftChild = node;
}else {
count = 0;
cur.rightChild = node;
}
if(data[i] != '#'){
q.enqueue(node);
}
}
class Node{
int data;
Node leftChild, rightChild;
}
Note: this should only work for a binary tree and not BST.
we can build this binary tree from level order traversal by maintaining a queue. Queue is used to maintain those nodes that are not yet processed.
Using a variable count(index variable) to keep track of the number of children added for the current node.
First, create a root node, assign it as the current node. So starting from index 1,
index value is 1 means, we will add the next value as left node.
index value is 2 means we will add the next value as right node and index value 2 means that we have added left and right node, then do the same for the remaining nodes.
if arr value is -1
3.a. if index value is 1,i.e., there is no left node then change the index variable to add right node.
3.b. if index value is 2, i.e, there is no right node then we have repeat this step for the remaining.
static class Node{
int data;
Node left;
Node right;
Node(int d){
data=d;
left=null;
right=null;
}
}
public static Node constBT(int arr[],int n){
Node root=null;
Node curr=null;
int index=0;
Queue<Node> q=new LinkedList<>();
for(int i=0;i<n;i++){
if(root==null){
root=new Node(arr[i]);
q.add(root);
curr=q.peek();
index=1;
}else{
if(arr[i]==-1){
if(index==1)
index=2;
else{
q.remove();
curr=q.peek();
index=1;
}
}
else if(index==1){
curr.left=new Node(arr[i]);
q.add(curr.left);
index=2;
}else if(index==2){
curr.right=new Node(arr[i]);
q.add(curr.right);
q.remove();
curr=q.peek();
index=1;
}
}
}
return root;
}
My approach is similar to Pham Trung yet intutive. We would maintain an array of Nodes of given data instead of using a queue. We would do reverse engineering on BFS using queue. because BFS for a tree is basically its Level Order Traversal (LOT).
It is important to note that we should have the NULL childs of an node for the LOT to be unique and the reconstruction of Tree from LOT to be possible.
In this case LOT : 1,2,3,-1,-1,4,-1,-1,5
where I have used -1 instead of '#' to represent NULLs
And Tree is
1
/ \
2 3
/ \ /
-1 -1 4
/ \
-1 5
Here, we can easily see that when 1 is popped from the BFS queue, it pushed its left child
(2) and right child (3) in the queue. Similary, for 2 it pushed -1 (NULL) for both of its children. And the process is continued.
So, we can follow the following pseudo code to generate the tree rooted at LOT[0]
j = 1
For every node in LOT:
if n<=j: break
if node != NULL:
make LOT[j] left child of node
if n<=j+1: break
make LOT[j+1] right child of node
j <- j+2
Finally, C++ code for the same
Class Declaration and Preorder traversal
class Node{
public:
int val;
Node* lft, *rgt;
Node(int x ):val(x) {lft=rgt=nullptr;}
};
void preorder(Node* root) {
if(!root) return;
cout<<root->val<<" ";
preorder(root->lft);
preorder(root->rgt);
}
Restoring Tree from LOT Logic
int main(){
int arr[] = {1,2,3,-1,-1,4,-1,-1,5};
int n = sizeof(arr)/sizeof(int);
Node* brr[n];
for(int i=0;i<n;i++) {
if(arr[i]==-1) brr[i] = nullptr;
else brr[i] = new Node(arr[i]);
}
for(int i=0,j=1;j<n;i++) {
if(!brr[i]) continue;
brr[i]->lft = brr[j++];
if(j<n) brr[i]->rgt = brr[j++];
}
preorder(brr[0]);
}
Output: 1 2 3 4 5
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.