I need help solving this problem. Only hints please
Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).
Example
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public boolean isSymmetric(TreeNode root) {
if((root == null) || (root.left == null && root.right == null)){return true;}
}
public boolean helper(TreeNode left, TreeNode right){
}
}
The trouble I am having is somehow creating a recursive problem out of this. I am confused because as we branch out, how do I compare one back to the other using helper?
Can someone provide hints?
Recursively call your helper method like following
if (left != null && right != null && left.key == right.key)
return (helper(left.left, right.right)
&& helper(left.right, right.left));
Note that,
we are checking whether the left of the left node and right of the right node is symmetric and right of the left node and left of the right node is symmetric. If both are symmetric then the main tree will be too.
If only root return true.
Else remove root and you will get two sub tress, compare the root with other sub tree. If they are same and have no sub tree return true. Else again remove the root and you will get the two sub tree. Follow the 2nd step again until you will find only one root node. If you find root node on one sub tree but null on other return false.
Related
Here is the code for the implementation of the Binary Search Tree:
public class BST<T extends Comparable<T>> {
BSTNode<T> root;
public T search(T target)
{
//loop to go through nodes and determine which routes to make
BSTNode<T> tmp = root;
while(tmp != null)
{
//c can have 3 values
//0 = target found
//(negative) = go left, target is smaller
//(positive) = go left, target is greater than current position
int c = target.compareTo(tmp.data);
if(c==0)
{
return tmp.data;
}
else if(c<0)
{
tmp = tmp.left;
}
else
{
tmp = tmp.right;
}
}
return null;
}
/*
* Need a helper method
*/
public T recSearch(T target)
{
return recSearch(target, root);
}
//helper method for recSearch()
private T recSearch(T target, BSTNode<T> root)
{
//Base case
if(root == null)
return null;
int c = target.compareTo(root.data);
if(c == 0)
return root.data;
else if(c<0)
return recSearch(target, root.left);
else
return recSearch(target, root.right);
}
Why do I need the recursive helper method? Why can't I I just use "this.root" to carry out the recursive process that is taking place? Furthermore, if screwing up the root property of the object this method is being called on is a problem, then how is does the helper method prevent this from happening? Does it just create a pointer that is separate from the this.root property, and therefore won't mess up the root property of the object that the method is being called on?
Sorry if the question doesn't seem straight forward, but if anyone can enlighten me on what's exactly going on behind the scenes I would really appreciate it.
The method needs a starting point. It needs to have a non changing Target node and it needs to compare it with some other node to see if they are a match lets call this node current instead of root since it is the current Node the recursive method is evaluating. There really isn't a concise way of doing this when using a recursive method other than using a helper function and passing in both variables (this is the case for many recursive methods). As you said stated if you updated root you would completely alter your tree when going left or right which you wouldn't want to do. The helper function is used because it gives your recursive method a starting point. And it also keeps track of the current node you are working on as you said the method points to the Node object being evaluated but doesn't make any changes. When going left or right it doesn't modify anything it just passes in a reference to the left or right node and continues to do this until the target is found or the base case is hit.
Because the code is too long the link is here ->http://pastebin.com/jXgbE6bB
Because i am not that good at recursions i just can't find the right recursion function for this problem.
(P.S.I am new to this forum and i know i am going to have a lot of hate comments like why not go find tutorials on recursions and other things,but believe me i have done everything but i just can't understand the logic of the recursions)
My question is What's the recursive function for in-order successor of a given element in Binary search tree?I made it this far but it just returns the parent of the node it's supposed to print:
public E getSuccessor(BNode<E> t, E x) {
if(t.left!=null && x.equals(t.info)){
return t.left.info;
}
else if(x.compareTo(t.info)<0){
return (getSuccessor(t.left, x));
}
else {
return (getSuccessor(t.right, x));
}
}
public E getSuccessor(E x) {
return getSuccessor(root, x);
}
The inorder successor of a given node is the lowest node in the right subtree of that node. To understand otherwise, it is the next node that will be printed in a simple in order traversal of the tree.
If the node has a right child, this solution is simplified to finding the smallest node in the right subtree.
If the node doesn't have a right child, and there are no parent pointers, we need to start from the root of the tree and work our way to identify this successor.
Here is the recursive way to solve this. While calling the method, pass root as the root of the tree, the node who's successor is needed as t and null as the successor because the method will calculate it. Something like the following -
BinaryTreeNode successor=tree.inorderSuccessor(root,node,null);
public BinaryTreeNode<Type> inorderSuccessor(BinaryTreeNode<Type> root,BinaryTreeNode<Type> t,BinaryTreeNode<Type> successor)
{
if(root==null)
return null;
if(root.element==t.element)
{
if(root.right!=null)
return findMin(root.right);
else
return successor;
}
int cmp=t.element.compareTo(root.element);
if(cmp < 0)
return inorderSuccessor(root.left,t,root);
else
return inorderSuccessor(root.right,t,successor);
}
public BinaryTreeNode<Type> findMin(BinaryTreeNode<Type> t)
{
if(t==null)
return t;
while(t.left!=null)
t=t.left;
return t;
}
I have two trees. The tree Node is defined as
class Node{
String treeId;
String type; //Each node has type which has fixed value. For example, its color: RED, BLANK, GREEN
Set<Node> children;
String ref; //The ref is a string and allowed value are "0", "1",..."10". The value is null if it is not leaf.
};
For leaf, the children set is empty.
I am wondering whether there is some existing efficient work done how to identify equivalent substree for two given tree. The equivalent is defined as:
1) Both subtree leaves are setsets leaves of original tree.
2) Both subtrees leaves have same ref value.
3) for non-leaves node, the equivalent refers to both node have same type and equivalent children.
Thanks. It would be better if there is some Java library addressing this problem.
The input should are two tree roots while output is the Node that is root of equivalent subtree. An the the tree's height is 100~ and it has more than 500 nodes.
What i did now is that I added a new field for class Node.
class Cache{
Map<String, Set<String>> map = new LinkedHashMap<String, Set<Str>>();
}
The key of map is Node id while the value is a ref set this node of this nodeid can reach. The Cache initiated when Node is initialized.
During isEquivalent compare phase, check whether overlap exists between two root's ref set. Return false if none.
I think this can help reduce the number of comparison space.
I am not sure about 1) Both subtree leaves are leaves of original tree. requirement as it seems to conflict with how to identify equivalent substree for two given tree.. Otherwise following recursive method should be able to cover other two conditions. The haveSameOriginalTree(r1, r2) method may be implemented to satisfy the first condition that I couldn't understand. r1 and r2 are roots of two subtrees that need to be checked for equivalence.
bool areEquivalent(Node r1, Node r2)
{
if(r1.children == null && r2.children == null)
{
return (haveSameOriginalTree(r1, r2) && (r1.ref == r2.ref));
}
if((r1.children == null && r2.children != null) || (r1.children != null && r2.children == null))
{
return false;
}
// if here then both must be non-leaf nodes
if(r1.type != r2.type)
{
return false;
}
if(r1.children.getCount() != r2.children.getCount()) // not sure of correct syntax for Java Sets
{
return false;
}
for(int i=0; i<r1.children.getCount(); i++)
{
if(!areEquivalent(r1.children[i], r2.children[i])) // again please correct the syntax for Sets
{
return false;
}
}
return true;
}
Let me know what you think.
Update
Here is an iterative version of the above solution. It uses stack data structure which is allocated on the heap rather than pushed on function's call stack, so not hugely different from recursive but still better. Also, since we only hold references to Nodes (rather than copying the whole object), this shouldn't be that much of an additional memory overhead if we are already loading the original tree into memory.
bool areEquivalent(Node r1, Node r2)
{
Stack<Node> s1 = new Stack<Node>();
Stack<Node> s2 = new Stack<Node>();
Node n1, n2;
s1.Push(r1);
s2.Push(r2);
while(true) // Need a better check
{
if(s1.getCount() != s2.getCount())
{
return false;
}
if(s1.getCount() == 0) // if both stacks are empty then we've traversed both trees without failure.
{
return true;
}
n1 = s1.Pop();
n2 = s2.Pop();
if(!areEquivalentNodes(n1, n2))
{
return false;
}
foreach(Node child in n1.children)
{
s1.Push(child);
}
foreach(Node child in n2.children)
{
s2.Push(child);
}
}
}
// only checks the two nodes are equivalent. their childrens' equivalence will be handled by other calls to this method.
bool areEquivalentNodes(Node n1, Node n2)
{
if(n1.children.getCount() != n2.children.getCount())
{
return false;
}
if(n1.children.getCount() == 0) // if both are leaf nodes...
{
if(n1.ref != n2.ref)
{
return false;
}
}
else // both are non-leaf
{
if(n1.type != n2.type)
{
return false;
}
// the condition that children of non-leaf nodes be equivalent will be covered by subsequent calls this method...
}
return true;
}
Please note that both solutions expect children of two equivalent nodes in the same order. If children are not ordered then we will need to sort them before calling above code.
Let me know if this is better.
Trying to add an element to BST. I have an idea of how to do it, but my implementation is destructive, and the original root is not preserved (so the tree basically becomes useless). The tree is based on lists, and this method is based on recursion. My real problem is preserving the original root. I'm using generics.
So far what I have:
public void addElement(E elem, Node<E> root) {
Create node with a value of elem, call it newNode
Case 1: Tree is empty
root = newNode();
return; //End of method.
Otherwise, keep searching the tree (by comparing the value of out node a with the root of the tree.
if (!root.hasLeft() && !root.hasRight) { //if the root in question has no children
if (elem < rootValue) { //Set the element as the left element
root.setLeft(newNode);
}
else { //Set the element as the right element.
root.setRight(newNode);
}
}
else {
if (E < root.getElem()) {
//This is where the value of our node is compared to the value of the root, which we passed in.
//(I know that we can't use the < and > operators with generics, but assume it works).
root = root.getLeft() //Left node is new root
addElement(elem, root); //Call the method again
}
else {
root = root.getRight(); //Right node is new root
addElement(elem, root) //Call method again
}
}
}
Forgive me if this is a duplicate/vague question, this is my first post on SO, and I'm kind of noob.
if (!root.hasLeft() && !root.hasRight) {
This logic is wrong. You're only considering "setting" the left child, if you have neither a left nor right child. This change should do it:
void addElement(elem, root)
{
if (elem < root.value) {
if(!root.hasLeft())
root.setLeft(newNode);
else
addElement(elem, root.getLeft());
}
else {
if(!root.hasRight())
root.setRight(newNode);
else
addElement(elem, root.getRight());
}
}
You should not be changing root of the class, just passing it into the next method call. This should preserve root.
By the way, I assume you have rootValue = root.value somewhere or somethign similar?
I'm writing a mirror image method for a binary tree. The way my class works is I have an abstract class BinaryTree, with subclasses EmptyTree and ConsTree. I'm having trouble writing the method for the ConsTree. The class looks something like this:
public class ConsTree<T> extends BinaryTree<T>
{
BinaryTree<T> left;
BinaryTree<T> right;
T data;
public BinaryTree<T> mirrorImage()
{
ConsTree<T> tree = new ConsTree<T>(this.data, this.right, this.left); //In the constructor, the second parameter sets the left tree, so creates a new tree with the left and right trees swapped
if(this.left == null && this.right == null)
return tree;
if(this.left == null)
return tree + this.right.mirrorImage();
else if(right == null)
return tree + this.left.mirrorImage();
return tree + this.left.mirrorImage() + this.right.mirrorImage();
}
Obviously this doesn't work because I can't use a '+' operator with BinaryTree objects, however this is the basic idea of what I want to accomplish. I'm just a little confused with how to combine the trees together. Any help is appreciated. Thanks.
I take it that BinaryTree does not have the mirror method.
In this case, your return type should not be BinaryTree<T> but ConstTree<T>, because you will need the branches to implement mirrorImage().
I find puzzling that you assign the branches to the returned tree in the constructor, before you have the mirror of the branches. The logic would be
1) Get the mirror of branch left and right
2) Create a tree with the mirror images.
You are setting some values that you will never use there.
How do you want to return both the tree and the right mirrorImage!? Simply, return
this.right.mirrorImage();
this.left.mirrotImage();
instead of
tree + this.right.mirrorImage();
tree + this.left.mirrorImage();
public class BinaryTreeMirror {
public static TreeNode mirrorOf(TreeNode rootNode) {
if (rootNode == null) {
return rootNode;
} else {
TreeNode temp = rootNode.right;
rootNode.right = rootNode.left;
rootNode.left = temp;
mirrorOf(rootNode.right);
mirrorOf(rootNode.left);
}
return rootNode;
}
}