Leetcode:Binary Tree Inorder Traversal.problem:Memory Limited exceeded - binary-tree

The following code performs a binarytree inorder traversal. When I execute it in Leetcode, I receive a Run Status Code: Memory Limit Exceeded. Could someone explain what is causing this error?
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
if(root==NULL)
return res;
stack<TreeNode*> st;
st.push(root);
while(st.empty()==0){
TreeNode* cur=st.top();
st.pop();
if(cur->right!=NULL)//right childtree is not NULL,push
st.push(cur->right);
if(cur->left!=NULL){//left childtree is not NULL,push
st.push(cur);
st.push(cur->left);
}
else //if left child tree is NULL,store the value
res.push_back(cur->val);
}
//inorder(root,res);
return res;
}

Your code only stores a value into the result stack if the left child node is a null.
However, for your example, node 2 left child node is never set to a null and hence it is never inserted into the result stack but it is in the st stack. If you print out your output, you can observe that 3 is inserted in a loop, hence causing a memory issue.
A possible strategy to keep track of the ancestor:
Check for trivial case.
Prepare a stack to keep the ancestors, and one to keep the result.
While the stack is non-empty or if the root is not null
if the root is not null:
insert the root onto the ancestor stack.
update the root to be the left child of the root, possibly to be null.
if the root is null (meaning dead end from the left)
visit the stack, pop the top element to be the root.
add the root to the result stack
assign the right child of the root to be the root, possibly to be a null.

Related

Pseudo code to check if binary tree is a binary search tree - not sure about the recursion

I have homeowork to write pseudo code to check if a valid binary tree is a search binary tree.
I created an array to hold the in-order values of the tree. if the in-order values are in decreasing order it means it is indeed BST. However I've got some problem with the recursion in the method InOverArr.
I need to update the index of the array in order to submit the values to the array in the order they are at the tree.
I'm not sure the index is really updated properly during the recursion.. is it or not? and if you see some problem can you help me fix this? thanks a lot
pseudo code
first function
IsBST(node)
size ← TreeSize(node)
create new array TreeArr of Size number of cells
index ← 0
few comments:
now we use the IN_ORDER procedure with a small variation , I called the new version of the procedure: InOrderArr
the pseudo code of InOrderArr is described below IsBST
InOrderArr(node, TreeArr, index)
for i from 1 to size-1 do
if not (TreeArr[i] > TreeArr[i-1]) return
false
return true
second function
InOrderArr (node, Array, index)
if node = NULL then return
else
InOrderArr (node.left, Array, index)
treeArr[index] = node.key
index ← index + 1
InOrderArr (node.right, Array, index)
Return
Your code is generally correct. Just three notes.
The correctness of the code depends on the implementation, specifically on the way of index handling. Many programming languages pass arguments to subroutines by value. That means the subroutine receives a copy of the value and modifications made to the parameter have no effect on the original value. So incrementing index during execution of InOrderArr (node.left, Array, index) would not affect the position used by treeArr[index] = node.key. As a result only the rightmost path would be stored in the array.
To avoid that you'll have to ensure that index is passed by reference, so that incrementation done by a callee advances the position used later by a caller.
BST is usually defined so that the left subtreee of a node contains keys that are less than that node's key, and the right subtree contains nodes with greater keys – see Wikipedia's article on BST. Then the inorder traversal retrieves keys in ascending order. Why do you expect descending order?
Possibly it would be more efficient to drop the array and just recursively test a definition condition of BST?
Whenever we follow a left link we expect keys which are less than the current one. Whenever we follow the right link we expect keys greater the the current one. So for most subtrees there is some interval of keys values, defined by some ancestor nodes' keys. Just track those keys and test whether the key falls inside the current valid interval. Be sure to handle 'no left end defined' condition on the letfmost path and 'no right end' on the rightmost path of the tree. At the root node there's no ancestor yet, so the root key is not tested at all (any value is OK).
EDIT
C code draft:
// Test a node against its closest left-side and right-side ancestors
boolean isNodeBST(NODE *lt, NODE *node, NODE *rt)
{
if(node == NULL)
return true;
if(lt != NULL && node->key < lt->key)
return false;
if(rt != NULL && node->key > rt->key)
return false;
return
isNodeBST(lt, node->left, node) &&
isNodeBST(node, node->right, rt);
}
boolean isTreeBST(TREE *tree)
{
return isNodeBST( NULL, tree->root, NULL);
}

Deleting any node from a single linked list when only pointer to that node is given

This is a question posed to me in an interview.
"A single linked list is there in the memory. You have to delete a node. You need to write a function to delete that node, which takes only the address of the node to be deleted as input and nothing else(including head)"
I gave the answer similar to the one answered in the below post -- Copying the contents of the next node into the node to be deleted and deleting the next one.
Deleting a middle node from a single linked list when pointer to the previous node is not available
But the interviewer asked me again, what if I pass the address of the last node. I told him, since the next will be a NULL, copy that NULL into the data field along with the address to the next node which is also NULL. Then he told me there will be a problem of dangling pointers... which I didn't understand a bit. Can some one please throw light into this problem ? Is there a generic solution to this ?
Update (Two days later) : A little bit additional. Considering there is no special node at the end of the list. And the last node points to NULL and if that node is given as input, how to make the before last node point to NULL. Or is it impossible ?
Simply put : If a node is given as input to a function, how to make the pointer that references it, point to NULL
Steps:
Copy data from Node(i+1) to Node(i)
Copy the NEXT of second Node(i+1) into a temporary variable.
Now Delete the second Node(i+1) // it doesn't require pointer to the previous node.
Function:
void delete_node(node* node)
{
node->Data = node->Next->Data;
node* temp = node->Next->Next;
delete(node->Next);
node->Next = temp;
}
Dangling Pointer:
(http://en.wikipedia.org/wiki/Dangling_reference)
Dangling pointers and wild pointers in computer programming are
pointers that do not point to a valid object of the appropriate type.
These are special cases of memory safety violations.
Dangling pointers arise when an object is deleted or deallocated,
without modifying the value of the pointer, so that the pointer still
points to the memory location of the deallocated memory. As the system
may reallocate the previously freed memory to another process, if the
original program then dereferences the (now) dangling pointer,
unpredictable behavior may result, as the memory may now contain
completely different data.
In your answer, to delete the given node you actually delete the next node, which might be being referenced by a pointer. That's how dangling pointer problem arise.
(1) There are no outside references to the list, as you clarify in a note.
(2) Dangling pointer problem can arise, as the interviewer said.
Both (1) and (2) cannot be correct at the same time. Which means there is a misunderstanding somewhere.
About Deleting the Last Node:
But the interviewer asked me again, what if I pass the address of the
last node. I told him, since the next will be a NULL, copy that NULL
into the data field along with the address to the next node which is
also NULL.
I think you are confusing these two things: (1) A pointer p that points to NULL, (2) A linked list node that has NULL in its data field.
Suppose the data structure is a -> b -> c -> d. Writing NULL to d's data field will not magicly make c to have a NULL pointer in its next field.
You can delete the last node if the linked list always has a special last node that will never be deleted. For example, a -> b -> c -> d -> LAST where LAST has a special value in its data field that denotes it is really the last element. Now to delete d, you could delete LAST and write the special value in d's data field.
Maybe these are exactly what you tried to tell during the interview, in which case there must have been some miscommunication between you and the interviewer.
Then there should be a check in the program whether the given node is the last node or not.
void delete_node(node* node1) {
node* search=head;
if(node1==head) {
head=head->next;
search->next=NULL;
node1->next=NULL;
}
while(search->next != node1)
search=search->next;
if(node1->next==NULL) {
search->next=NULL;
} else {
search->next=node1->next;
node1->next=NULL;
}
delete node1;
}
If there are other elements that are pointing to the next node which will be copied to the current node and then deleted, then this operation will introduce a bug. So in your answer you should have emphasized that your solution only works if there are no outside references to the list.
Your solution works with the last node only if the data structure is augmented with a specific "last node" element. (If you are using Smalltalk, you can write self become: nil No other language has anything similar)
No, there is no generic solution if there are outside references to the list. I think the interviewer wanted to see whether you are really knowledgable in the subject matter or were just repeating a memorized answer.
Probably your link list traversing might need to assume that any node that points to null is null node regardless of the value...
a->b->c->d->NULL
so d is null node and the node should not be considered as a node. this way you can save on using special values since they are not correct in a generic sense. other than that you will not have any other way for previous node to point to null.
When the last node is given, instead of deleting it, assign it to a dummy node and while displaying the data we can check for ptr->next as dummy node and terminate there.
In case of dangling pointer, I believe when the pointer is freed(deallocated), it will become dangling pointer and so after freeing assign it to NULL.
Below will be my code snippet for this Question:
dummy-> data = NULL;
dummy-> next = NULL;
FUNC(del_ptr)
{
if (del_ptr->next == NULL )
{
del_ptr = dummy;
return;
}
struct node *next = del_ptr ->next;
del_ptr -> data = next -> data;
del_ptr -> next = next -> next;
free(next);
next=NULL;
}
Assumption: deleteNode() has reference to node pointer.
Simple solution without a while loop. In deleteNode(), if case handles deletion of head and intermediate node and else handles deletion of last node.
#include <iostream>
using namespace std;
class Node{
public:
int data;
Node* next;
Node(int d): data(d){}
};
void insert(Node* &head, int data){
Node *node = new Node(data);
node->next = head;
head = node;
}
void print(Node *head){
Node *temp = head;
while(temp !=NULL){
cout << temp->data <<" ";
temp = temp->next;
}
cout << endl;
}
void deleteNode(Node *&node){
cout << "Deleting "<<node->data<<endl;
if(node->next != NULL){
Node *t = node->next;
node->data = node->next->data;
node->next = node->next->next;
delete t;
}else{
delete node;
node = NULL;
}
}
int main(int argc, char const *argv[]) {
Node *head = NULL;
insert(head, 10);
insert(head, 20);
insert(head, 30);
insert(head, 40);
insert(head, 50);
print(head);
deleteNode(head->next); //delete 40
deleteNode(head->next->next->next); //delete last node 10
print(head);
return 0;
}
public void removeNode(Node node){
/* if no node return null */
if(node==null) return;
/* if only 1 node then delete node */
if(node.getNext()==null) {
node = null;
return ;
}
/* copy next node data to this node */
node.data = node.getNext().data();
/* store the next next node */
Node second = node.getNext().getNext();
/* remove next node */
removeNode(node.getNext());
/* set the copied node as next */
node.setNext(second);
}

Print nodes of two binary trees in ascending order

Given two binary search trees, print the nodes in ascending order with time complexity O(n) and space complexity: O(1)
The trees cannot be modified. Only traversal is allowed.
The problem I am facing is with the O(1)space solution. Had there not been this constraint, it could have been easily solved.
The only way this can be done in space O(1) is if the nodes know their parent.
Otherwise you cannot even traverse the tree unless there is some additional aid.
However with this constraint it's again easy and back to tree-traversal, but without recursion. The tricky part is probably knowing which tree-path you came from when you go from a node to its parent (p) and cannot store this information as this would require O(log N) space.
However, you know the last value you outputted. If it is smaller than the one of p, go the right, otherwise go to p’s parent.
if we're talking about BST's as defined by wikipedia:
The left subtree of a node contains only nodes with keys less than the node's key.
The right subtree of a node contains only nodes with keys greater than the node's key.
Both the left and right subtrees must also be binary search trees.
with the additional perk that every node knows his parent, then the following C code does the trick (I hope you like C, I have put quite some effort in these 300 lines of demo application :D)
http://pastebin.com/MiTGqakq
(note that I didn't use recursion, because recursion is technically never O(1)space. The reason for this that every function call uses copies of the passed parameters, thus allocating additional space, making O_space dependent on the number of calls -> not in O(1)space.)
EDIT: ok, fixed version is linked. have fun.
I have solution of this problem.
I have coded my solution in C#, because it is my strongest language, but I hope that you will catch a main idea. Let's suppose, that each tree node has 3 references: to left, right and parent nodes.
So we have BinaryTree. How could we print it? Obviously:
this._tree.Print();
That wasn't very difficult. But how could we build Print method, if we should avoid recursion (because the last one involves O(log(n)) memory)? Have you ever read about lazy lists (or streams)? Lazy list doesn't hold the whole list in memory, but knows how to calculate next item based on current item. In every moment lazy list allocates O(1) memory. So, suppose we have managed to describe lazy list for tree. Then Print method is very simple:
public static void Print<T>(this BinaryTree<T> tree)
where T : IComparable<T>
{
var node = new TreeNodeWalker<T>(tree.Root, WalkerState.FromParent);
while (node != null)
{
node = node.WalkNext();
}
}
During this code snippet you could find out one unfamiliar entity: TreeNodeWalker. This object holds tree node that should be walked, state that signals in what moment of traversing this walker was created and method which gives next walker. In short walker performs next actions:
If we drop in any subtree from parent node, we should walk left subtree.
If we emerges from left subtree, we should print node value and walk right subtree.
If we emerges from right subtree we should walk parent.
It could be represented in code in the next way:
public class TreeNodeWalker<T>
where T:IComparable<T>
{
// Tree node, for which walker is created.
private readonly BinaryTreeNode<T> _node;
// State of walker.
private readonly WalkerState _state;
public TreeNodeWalker(BinaryTreeNode<T> node, WalkerState state)
{
this._node = node;
this._state = state;
}
public TreeNodeWalker<T> WalkNext()
{
if (this._state == WalkerState.FromParent)
{
// If we come to this node from parent
// we should walk left subtree first.
if (this._node.Left != null)
{
return new TreeNodeWalker<T>(this._node.Left, WalkerState.FromParent);
}
else
{
// If left subtree doesn't exist - return this node but with changed state (as if we have already walked left subtree).
return new TreeNodeWalker<T>(this._node, WalkerState.FromLeftSubTree);
}
}
else if (this._state == WalkerState.FromLeftSubTree)
{
// If we have returned from left subtree - current node is smallest in the tree
// so we should print it.
Console.WriteLine(this._node.Data.ToString());
// And walk right subtree...
if (this._node.Right != null)
{
//... if it exists
return new TreeNodeWalker<T>(this._node.Right, WalkerState.FromParent);
}
else
{
// ... or return current node as if we have returned from right subtree.
return new TreeNodeWalker<T>(this._node, WalkerState.FromRightSubTree);
}
}
else if (this._state == WalkerState.FromRightSubTree)
{
// If we have returned from right subtree, then we should move up.
if (this._node.Parent != null)
{
// If parent exists - we compare current node with left parent's node
// in order to say parent's walker which state is correct.
return new TreeNodeWalker<T>(this._node.Parent, this._node.Parent.Left == this._node ? WalkerState.FromLeftSubTree : WalkerState.FromRightSubTree);
}
else
{
// If there is no parent... Hooray, we have achieved root, which means end of walk.
return null;
}
}
else
{
return null;
}
}
}
You could see a lot of memory allocation in code and make decision that O(1) memory requirement is not fulfilled. But after getting next walker item, we don't need previous one any more. If you are coding in C++ don't forget to free memory. Alternatively, you could avoid new walker instance allocation at all with changing internal state and node variables instead (you should always return this reference in corresponding places).
As for time complexity - it's O(n). Actually O(3*n), because we visit each node three times maximum.
Good luck.

How to convert a recursive function to use a stack?

Suppose that I have a tree to traverse using a Depth First Search, and that my algorithm for traversing it looks something like this:
algorithm search(NODE):
doSomethingWith(NODE)
for each node CHILD connected to NODE:
search(CHILD)
Now in many languages there is a maximum depth to recursion, for example if the depth of recursion is over a certain limit, then the procedure will crash with a stack overflow.
How can this function be implemented without the recursion, and instead with a stack? In many cases, there are a lot of local variables; where can they be stored?
You change this to use a stack like so:
algorithm search(NODE):
createStack()
addNodeToStack(NODE)
while(stackHasElements)
NODE = popNodeFromStack()
doSomethingWith(NODE)
for each node CHILD connected to NODE:
addNodeToStack(CHILD)
As for your second question:
In many cases, there are a lot of local variables; where can they be stored?
These really can be kept in the same location as they were originally. If the variables are local to the "doSomethingWith" method, just move them into that, and refactor that into a separate method. The method doesn't need to handle the traversal, only the processing, and can have it's own local variables this way that work in its scope only.
For a slightly different traversal.
push(root)
while not empty:
node = pop
doSomethingWith node
for each node CHILD connected to NODE:
push(CHILD)
For an identical traversal push the nodes in reverse order.
If you are blowing your stack, this probably won't help, as you'll blow your heap instead
You can avoid pushing all the children if you have a nextChild function
Essentially you new up your own stack: char a[] = new char[1024]; or for type-safety, node* in_process[] = new node*[1024]; and put your intermediate values on this:
node** current = &in_process[0];
node* root = getRoot();
recurse( root, &current) ;**
void recurse( node* root, node** current ) ;
*(*current)++ = root; add a node
for( child in root ) {
recurse( child, current );
}
--*current; // decrement pointer, popping stack;
}

Right Threading a Binary Tree

I'm having a hell of a time trying to figure this one out. Everywhere I look, I seem to be only running into explanations on how to actually traverse through the list non-recursively (the part I actually understand). Can anyone out there hammer in how exactly I can go through the list initially and find the actual predecessor/successor nodes so I can flag them in the node class? I need to be able to create a simple Binary Search Tree and go through the list and reroute the null links to the predecessor/successor. I've had some luck with a solution somewhat like the following:
thread(node n, node p) {
if (n.left !=null)
thread (n.left, n);
if (n.right !=null) {
thread (n.right, p);
}
n.right = p;
}
From your description, I'll assume you have a node with a structure looking something like:
Node {
left
right
}
... and that you have a binary tree of these set up using the left and right, and that you want to re-assign values to left and right such that it creates a doublely-linked-list from a depth first traversal of the tree.
The root (no pun intended) problem with what you've got so far is that the "node p" (short for previous?) that is passed during the traversal needs to be independent of where in the tree you currently are - it always needs to contain the previously visited node. To do that, each time thread is run it needs to reference the same "previous" variable. I've done some Python-ish pseudo code with one C-ism - if you're not familiar, '&' means "reference to" (or "ref" in C#), and '*' means "dereference and give me the object it is pointing to".
Node lastVisited
thread(root, &lastVisisted)
function thread(node, lastVisitedRef)
if (node.left)
thread(node.left, lastVisitedRef)
if (node.right)
thread(node.right, lastVisitedRef)
// visit this node, reassigning left and right
if (*lastVisitedRef)
node.right = *lastVisitedRef
(*lastVisitedRef).left = node
// update reference lastVisited
lastVisitedRef = &node
If you were going to implement this in C, you'd actually need a double pointer to hold the reference, but the idea is the same - you need to persist the location of the "last visited node" during the entire traversal.

Resources