I am trying to construct BST From PreOrder And inorder
// Construct Binary Tree From Inorder And Preorder
public class Solution {
public TreeNode buildTree(ArrayList<Integer> A, ArrayList<Integer> B) {
return buildTreeUtil(A,0,A.size()-1,B,0,B.size()-1);
}
public TreeNode buildTreeUtil(ArrayList<Integer> inOrder,int inOrderStart,int inOrderStop,
ArrayList<Integer> preOrder,int preOrderStart,int preOrderStop){
if(inOrderStart > inOrderStop || preOrderStart>preOrderStop){
return null;
}
TreeNode root = new TreeNode(preOrder.get(preOrderStart));
int index = 0;
for(int i=0;i<inOrder.size()-1;i++){
if(inOrder.get(i)==preOrder.get(preOrderStart)){
index = i;
break;
}
}
root.left = buildTreeUtil(inOrder,inOrderStart,index-1,
preOrder,preOrderStart+1,preOrderStart+(index-inOrderStart));
root.right = buildTreeUtil(inOrder,index+1,inOrderStop,
preOrder,preOrderStart+index-inOrderStart+1,preOrderStop);
return root;
}
}
It's giving exception
Index out of bound
Unrelated to the IndexOutOfBoundsException, but the following line of code is improperly using the equality operator == to compare two Integer instances, instead it should use the .equals() method:
Bad code:
if(inOrder.get(i)==preOrder.get(preOrderStart)){
Correct code:
if(inOrder.get(i).equals(preOrder.get(preOrderStart))) {
The IndexOutOfBoundsException is likely occurring because the following lines of code are not protected against preOrderStart and preOrderStop parameter values that are negative or greater than the ArrayList's size()-1:
root.left = buildTreeUtil(inOrder,inOrderStart,index-1,
preOrder,preOrderStart+1,preOrderStart+(index-inOrderStart));
root.right = buildTreeUtil(inOrder,index+1,inOrderStop,
preOrder,preOrderStart+index-inOrderStart+1,preOrderStop);
Think about what happens in the code above if the variable index has a value of 0. The parameter index-1 will get a value of -1.
Related
Beginner here using Java (first year student), and am unable to get the below function to work. The goal is to use recursion and a helper function to compute the size of a singly linked list. When running the code against test lists, it keeps returning List changed to [].
I'm struggling in general with Java, so any help is appreciated. Thank you
public class MyLinked {
static class Node {
public Node(double item, Node next) {
this.item = item;
this.next = next;
}
public double item;
public Node next;
}
int N;
Node first;
public int sizeForward() {
return sizeForwardHelper(first);
}
public int sizeForwardHelper(Node n) {
Node current = first;
if (current == null) {
return 0;
} else {
first = first.next;
return sizeForward() + 1;
}
}
I believe I have the first portion set up to return 0 if there are no elements in the List. I believe it's the second part that isn't setting up correctly?
Thanks
Because it’s important for your learning to not spoonfeed you, I’ll describe an approach rather than provide code.
Use this fact:
The length of the list from any given node to the end is 1 plus the length measured from the next node (if there is one).
Usually (as would work here), recursive functions take this form:
If the terminating condition is true, return some value
Otherwise, return some value plus the recursively calculated value
When writing a recursive function, first decide on the terminating condition. In this case, n == null is the obvious choice, and you’d return 0, because you’ve run off the end of the list and the length of nothing (ie no node) is nothing. This also handles the empty list (when first is null) without any special code.
Otherwise, return 1 (the length of one node) plus the length of next.
Put that all together and you’ll have your answer.
——
Hint: The body of the recursive helper method can be coded using one short line if you use a ternary expression.
Instead of calling your wrapper function call your helper function recursively. Try the following:
public int sizeForward () {
return sizeForwardHelper (first);
}
public int sizeForwardHelper(Node n) {
if (n == null) // base case
return 0;
return sizeForwardHelper(n.next) + 1; // count this node + rest of list
}
Your method that computes the size of the list actually modifies the list in the process (with first = first.next; you set the first element to the next, and since there is a recursion, the first element always end up being null which is equivalent to an empty list with your design). Your method will work once, but your list will be empty afterwards.
To illustrate this, I added a print next to the instruction first = first.next; and wrote the following main:
public static void main(String[] args) {
Node n2 = new Node(2d, null);
Node n1 = new Node(1d, n2);
Node n = new Node(0, n1);
MyLinked l = new MyLinked(n);
System.out.println("The first element is: "+l.first.item);
System.out.println("The size is: "+l.sizeForward());
System.out.println("The first element is: "+l.first);
}
It yields:
The first element is: 0.0
first is set to 1.0
first is set to 2.0
first is set to null
The size is: 3
The first element is: null
Clearly, you should not modify the list while computing its size. The helper method should return 0 if the node is null (empty list), and 1 plus the size of the rest of the list otherwise. Here is the code.
public int sizeForwardHelper(Node n) {
if (n == null)
return 0;
else
return sizeForwardHelper(n.next) +1;
}
The goal of the arg free method sizeForward() is just to call the helper. The helper should not use it though.
So I'm trying to find the largest "SSN" in a Binary Search Tree comprised of "Persons", where each Person node stores an SSN in their info. However, iterating through the debugger, once I get the largest SSN which should be 11, the program jumps back into the if loop for some reason even though the local root Node is now null.
// "highestSSN" is passed in as 0
// rootNode is passed in as the root of my BST
public static int largestSSN(Node<Integer, Person> rootNode, int highestSSN) {
if(rootNode != null) {
if (rootNode.info.SSN > highestSSN)
highestSSN = rootNode.info.SSN;
largestSSN(rootNode.rightChild, highestSSN);
}
return highestSSN;
}
The program returns highestSSN as 11 and the rootNode is null, but then it jumps back into the line that reads "largestSSN(rootNode.rightChild, highestSSN);", and re-evaluates everything from the root node that's 11 to the original root, in backwards order. I'm not sure why this is?
You should read the returned highestSSN. Try this:
public static int largestSSN(Node<Integer, Person> rootNode, int highestSSN) {
if(rootNode != null) {
//I think following 2 lines are useless, since BST already has rightNode.info.SSN greater than rootNode.SSN
if (rootNode.info.SSN > highestSSN)
highestSSN = rootNode.info.SSN;
highestSSN=largestSSN(rootNode.rightChild, highestSSN);//***CHANGED
}
return highestSSN;
}
The problem is with how you implement your recursive call largestSSN(rootNode.rightChild, highestSSN);, you keep repeating it even after you get the value, the trick is you just return once you get the maximum value, otherwise you do your recursive call
Also, you don't need highestSSN in your method arguments
public static int largestSSN(Node<Integer, Person> rootNode) {
if(rootNode.right == null) {
return rootNode.info.SSN
else{
return largestSSN(rootNode.rightChild);
}
}
I'm trying to understand the array-based implementation of Trie from http://www.programcreek.com/2014/05/leetcode-implement-trie-prefix-tree-java/ (see Java Solution 2 - Improve Performance by Using an Array).
public void insert(String word) {
TrieNode p = root;
for(int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
int index = c - 'a';
if(p.arr[index] == null) {
TrieNode temp = new TrieNode();
p.arr[index] = temp;
p = temp;
} else {
p = p.arr[index];
}
}
p.isEnd = true;
}
I'm not sure the else branch is ever executed. What am I missing?
Update 1
The given word only contains lower-case English letters
The first time you call this function, the else branch will indeed not execute. However, as the Trie gets populated, it is very possible that p.arr[index] is not null.
For example, calling insert("i") will cause add a new TrieNode at root.arr['i' - 'a']. Calling the function a second time, for example with insert("it"), will result in the check p.arr[index] == null returning false because the first insert already added the TrieNode for i at the root node.
You can test this out with the following main function (and putting a breakpoint or println statement in the else branch)
public static void main (String[] args)
{
Trie t = new Trie();
t.insert("i");
t.insert("it");
}
That looks to me pretty much like a bug. If c-'a'>26 then p.arr[index] won't be null but will raise an ArrayIndexOutOfBounds exception.
I have two recursive solutions to the "kth to last element of a singly linked list" problem in Java:
Solution 1:
public static Node nthToLast(Node head, int k , int i){
if (head == null) return null;
Node n = nthToLast(head.next, k, i);
i = i + 1;
if (i == k) return head;
return n;
}
Solution 2:
public class IntWrapper {
public int value = 0;
}
public static Node nthToLast(Node head, int k, IntWrapper i){
if (head == null) return null;
Node n = nthToLast(head.next, k, i);
i.value = i.value + 1;
if (i.value == k) return head;
return n;
}
The first solution returns null, while the second solution works perfectly. The first solution passes k by value, while the second solution wraps the int value in a class and passes it.
I have two questions:
Why is the first solution not working in Java? Why is pass-by-value through the local variable i in each method call not working the same as the pass-by-reference version?
The Integer class in Java wraps int, but replacing the int to Integer in the first solution does not work as well. Why?
1.
The first solution does not work because every time you pass the same value in a i variable. If you move the line i = i + 1 over the line Node n = nthToLast (head.next, k, i), everything should work without a problem.
2.
Integer class is immutable, so behaves like a normal int. That's why if you use an Integer in the first solution function will not work correctly. You can replace lines of code as I mentioned above that the first solution worked with an Integer.
The second solution works because the way you increment the counter does not overwrite the reference to the counting object.
In Solution 2, you're using IntWrapper to remember values across recursive invocations. Here, IntWrapper acts like a global value.
If you use local variables such as a primitive integer, you cannot preserve the incremented (i = i + 1) values across invocations. Therefore, the statement if (i == k) return head; never becomes true, unless maybe if k = 1.
Most interestingly, you cannot use Integer because Java wrapper classes are immutable in nature. The moment you do i = i + 1, a new object is created (LHS) and the old one (RHS) is thrown away/garbage collected.
In your solution 1 you should increment i before calling recursively the method. This version should work:
public static Node nthToLast(Node head, int k , int i) {
// checks empty case
if (head == null) { return null; }
// checks if current node is the solution
if (i == k) { return head; }
// else checks next node
return nthToLast(head.next, k, i+1);
}
Pretty easy question:
Recursively how can I create an array of a binary search tree (in order) which uses this constructor:
public class OrderedSet<E extends Comparable<E>> {
private class TreeNode {
private E data;
private TreeNode left, right;
public TreeNode(E el) {
data = el;
left = null;
right = null;
}
}
private TreeNode root;
public int size = 0;
public OrderedSet() {
root = null;
}
In-Order means you first have to traverse the left part of the tree, so:
TreeNode tree // this is your tree you want to traverse
E[] array = new E[tree.size]; // the arrays length must be equivalent to the number of Nodes in the tree
int index = 0; // when adding something to the array we need an index
inOrder(tree, array, index); // thats the call for the method you'll create
The method itself could looks something like this:
public void inOrder(TreeNode node, E[] array, int index){
if(node == null){ // recursion anchor: when the node is null an empty leaf was reached (doesn't matter if it is left or right, just end the method call
return;
}
inOrder(node.getLeft(), array, index); // first do every left child tree
array[index++]= node.getData(); // then write the data in the array
inOrder(node.getRight(), array, index); // do the same with the right child
}
Somewhat like that. I am just not sure about the index and where it needs to be incremented. If you don't want to worry about the index or if you don't know how many nodes are in the tree, then use an ArrayList instead and transform it in the end to an array.
Normally a cleaner call method is build around the recursive method like this:
public E[] inOrderSort(TreeNode tree){
E[] array = new E[tree.size];
inOrder(tree, array, 0);
return array;
}
Thanks, that worked great. Java wouldn't allow me to make an array of generics so using your algorithm I made it work with an ArrayList (like you suggested) Here's the method (using the above constructor) just incase someone else asks the same question. (Ref is my reference to the current tree node)
public ArrayList<E> toArray() {
ArrayList<E> result = new ArrayList<E>();
toArrayHelp(root, result);
return result;
}
private void toArrayHelp(TreeNode ref, ArrayList<E> result) {
if (ref == null) {
return;
}
toArrayHelp(ref.left, result);
result.add(ref.data);
toArrayHelp(ref.right, result);
}