I know how to find if a binary tree has a certain path with a given sum (If this is not the best way please let me know):
int pathSum(MyNode root, int sum)
{
if(root == null)
return -1;
int temp = sum - root.value;
return(pathSum(root.left,temp) || pathSum(root.right,temp));
}
What I am not able to figure out is how to print the particular path.
My Node class looks like this:
class MyNode {
int value;
MyNode left;
MyNode right;
MyNode(int value)
{
this.value = value;
}
}
Try this, use overloading:
public void pathToSum(int sum) {
pathToSum(root, sum);
}
private boolean pathToSum(Node n, int sum) {
if (null != n) {
sum -= n.data;
boolean found = pathToSum(n.left, sum);
if (!found) {
found = pathtoSum(n.right, sum);
}
if (found) {
println(n.data);
return found;
}
}
return 0 == sum ? true : false;
}
This code is tested with the following classes:
import java.util.LinkedList;
import java.util.Queue;
public class BST {
Node root;
public BST(){
root = null;
}
public void insert(int el){
Node tmp = root, p=null;
while(null!=tmp && el != tmp.data){
p=tmp;
if(el<tmp.data)
tmp=tmp.left;
else
tmp=tmp.right;
}
if(tmp == null){
if(null == p)
root = new Node(el);
else if(el <p.data)
p.left= new Node(el);
else
p.right=new Node(el);
}
}//
public void pathToSum(int sum) {
pathToSum(root, sum);
}//
private boolean pathToSum(Node n, int sum) {
if (null != n) {
sum -= n.data;
boolean found = pathToSum(n.left, sum);
if (!found) {
found = pathToSum(n.right, sum);
}
if (found) {
System.out.println(n.data);
return found;
}
}
return 0 == sum ? true : false;
}
public static void main(String[] args){
int[] input={50,25,75,10,35,60,100,5,20,30,45,55,70,90,102};
BST bst = new BST();
for(int i:input)
bst.insert(i);
bst.pathToSum(155);
}
}
class Node{
public int data;
public Node left;
public Node right;
public Node(int el){
data = el;
}
}
Result:
45
35
25
50
I suggest to alter your MyNode class to include a parent node:
MyNode left;
MyNode right;
MyNode parent;
MyNode(int value, MyNode parent)
{
this.value = value;
this.parent = parent;
}
and then when you hit a node with correct sum, you can pass that node to another function that goes throug the ancestry until it hits node with null parent (the root).
Nice puzzle, I liked it. You almost had it, just some confusion over int vs boolean, and not checking end condition of sum being zero.
public class NodeSums {
static boolean pathSum(MyNode root, int sum) {
boolean ret;
if (root == null) {
ret = sum == 0;
} else {
int remain = sum - root.value;
ret = pathSum(root.left,remain) || pathSum(root.right, remain);
}
return ret;
}
static class MyNode {
int value;
MyNode left;
MyNode right;
MyNode(int value) {
this.value = value;
}
}
public static void main(String[] args) {
/**
* Valid sums will be 3, 8, and 9
*
* 1 -- 2
* --
* -- 3 -- 4
* --
* -- 5
*/
MyNode root = new MyNode(1);
root.left = new MyNode(2);
root.right = new MyNode(3);
root.right.left = new MyNode(4);
root.right.right = new MyNode(5);
for (int i = 1; i < 10; i++) {
System.out.println("Path sum " + i + " " + pathSum(root, i));
}
}
}
Output
Path sum 1 false
Path sum 2 false
Path sum 3 true
Path sum 4 false
Path sum 5 false
Path sum 6 false
Path sum 7 false
Path sum 8 true
Path sum 9 true
If you store the parent of each node in MyNode, you can find the (reversed) path from the root to any node by getting the parent in a loop until it is null.
Also, your code for pathSum seems to be mixing booleans and ints, and you never check the value of sum.
Related
The question is to obtain median of given elements. If odd then simply return the middle element else return the mean of the n/2 and n/2 + 1 element.
The problem is that it is always returning 1 as the median, which probably means that rotation is not happening as 1 was my first input.
I know it is a famous leet code question, but i have written all my code by myself and there is no one else in the discussion panel whose code is written on avl tree from scratch.
Code:
'''
class Node{
int data;
Node left, right;
int height;
Node(int d){
this.data = d;
this.left = this.right = null;
this.height = 1;
}
Node(){
this.left = this.right = null;
}
}
class MedianFinder {
static Node root;
MedianFinder(){
root = new Node();
}
public void addNum(int num) {
insert(root, num);
}
public static Node insert(Node root, int num){
if(root == null)
return (new Node(num));
if(root.data < num){
root.right = insert(root.right, num);
}
else if(root.data > num)
root.left = insert(root.left, num);
root.height = max(height(root.left) , height(root.right)) + 1;
int balance = get_balance(root);
// if left left
if(balance > 2 && num < root.left.data){
return rightRotation(root);
}
// left right case
if(balance > 2 && num > root.left.data){
leftRotation(root.left);
return rightRotation(root);
}
// right right case
if(balance < -1 && num > root.right.data)
return leftRotation(root);
// right left case
if(balance < -1 && num < root.right.data){
rightRotation(root.right);
return leftRotation(root);
}
return root;
}
public static Node rightRotation(Node node){
Node temp = node.left;
Node tempright = temp.right;
temp.right = node;
node.left = tempright;
node.height = max(height(node.left), height(node.right)) + 1;
temp.height = max(height(temp.left), height(temp.right)) + 1;
return temp;
}
public static Node leftRotation(Node node){
Node temp = node.right;
Node templeft = temp.left;
temp.left = node;
node.right = templeft;
node.height = max(height(node.left), height(node.right)) + 1;
temp.height = max(height(temp.left), height(temp.right)) + 1;
return temp;
}
public static int get_balance(Node node){
if(node == null)
return 0;
return height(node.left) - height(node.right);
}
public static int height(Node node){
if(node == null)
return 0;
return node.height;
}
public static int max(int a, int b){
return a>b?a:b;
}
public double findMedian() {
if(height(root.left) == height(root.right))
return root.data;
return (root.data + root.right.data) / 2;
}
public static int count(Node node){
if(node == null)
return 0;
return 1 + count(node.left) + count(node.right);
}
}
/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder obj = new MedianFinder();
* obj.addNum(num);
* double param_2 = obj.findMedian();
*/
'''
I've been working on this coding problem and have been able to successfully get the depth of each leaf node into a hash set. What I'm trying to do is determine if the difference in depth is of a leaf node is greater than one BEFORE that depth is added to the hash set. I don't want to put all of the leaf nodes in the hash set and use two for loops to check if there is a difference in depth greater than one. In my code below, the int variable count represents depth.
The problem is my code always returns true. Something is wrong with the code where is checks the difference in depths/count for each leaf node. Code is below. I'm trying to keep this method in O(n) time, and avoid O(n^2).
The depths of the four leaf nodes in this tree are : 3, 2, 2, 5
import java.util.*;
public class cakeEightWeekly {
static int count = 0;
public static class Node {
public int value;
public Node leftChild;
public Node rightChild;
public Node(int value) {
this.value = value;
}
public void setLeft(Node leftValue) {
this.leftChild = leftValue;
}
public void setRight(Node rightValue) {
this.rightChild = rightValue;
}
public Node getRight() {
return rightChild;
}
public Node getLeft() {
return leftChild;
}
}
public static boolean isBalanced(Node root) {
HashSet < Integer > hset = new HashSet < Integer > ();
if (root != null) {
count++;
isBalanced(root.getLeft());
isBalanced(root.getRight());
count--;
if (root.getLeft() == null && root.getRight() == null) {
if (!hset.isEmpty()) {
for (int x: hset) {
if ((x - count) < 0) {
int sum = count - x;
if (sum > 1) {
return false;
}
} else if ((x - count) > 1) {
return false;
}
}
hset.add(count);
} else {
hset.add(count);
}
}
}
return true;
}
public static void main(String[] args) {
Node One = new Node(1);
Node Two = new Node(2);
Node Three = new Node(3);
Node Four = new Node(4);
Node Five = new Node(5);
Node Six = new Node(6);
Node Seven = new Node(7);
Node Eight = new Node(8);
Node Nine = new Node(9);
Node Ten = new Node(10);
Node Eleven = new Node(11);
Five.setLeft(Three);
Five.setRight(Seven);
Three.setLeft(Two);
Three.setRight(Four);
Two.setLeft(One);
Seven.setLeft(Six);
Seven.setRight(Eight);
Eight.setRight(Nine);
Nine.setRight(Ten);
Ten.setRight(Eleven);
System.out.print(isBalanced(Five));
}
}
I'm new in Java. I'm trying to obtain the height of my tree and the depth of every node in a huffman tree.
I have been trying different method to obtain the height but it's still not working.
I can't figure out whats the problem.
Right now I'm getting an error:
Exception in thread "main" java.lang.ClassCastException: HuffmanLeaf cannot be cast to HuffmanNode
at HuffmanCode.findHeight(HuffmanCode.java:95)
at HuffmanCode.printResults(HuffmanCode.java:71)
at Main.main(Main.java:31)
Please, I'm stuck on that.
import java.util.*;
public class HuffmanCode {
int numberOfNode = 1;
int height;
String fullcode = "";
String realcode = "";
// input is an array of frequencies, indexed by character code
public HuffmanTree createTree(int[] charFreqs) {
PriorityQueue<HuffmanTree> trees = new PriorityQueue<HuffmanTree>();
// initially, we have a forest of leaves
// one for each non-empty character
for (int x = 0; x < charFreqs.length; x++) {
if (charFreqs[x] > 0)
/*
* My first step of Huffman coding Create a leaf node for each
* character and add it to the priority queue with the offer
* method
*/
trees.offer(new HuffmanLeaf(charFreqs[x], (char) x));
}
while (trees.size() > 1) {
// Poll the two nodes with least frequency
HuffmanTree a = trees.poll();
HuffmanTree b = trees.poll();
// put into new node and re-insert into queue
trees.offer(new HuffmanNode(a, b));
numberOfNode++;
}
return trees.poll();
}
public void printResults(HuffmanTree tree, StringBuffer prefix) {
// assert tree != null;
if (tree instanceof HuffmanLeaf) {
HuffmanLeaf leaf = (HuffmanLeaf) tree;
System.out.println(leaf.value + "\t" + leaf.frequency + "\t" + prefix);
encodedInput(prefix);
for (int x = 0; x < leaf.frequency; x++) {
realcode = realcode + prefix;
}
} else if (tree instanceof HuffmanNode) {
HuffmanNode node = (HuffmanNode) tree;
numberOfNode++;
// move left
prefix.append('0');
printResults(node.left, prefix);
prefix.deleteCharAt(prefix.length() - 1);
findHeight(node);
// move right
prefix.append('1');
printResults(node.right, prefix);
prefix.deleteCharAt(prefix.length() - 1);
height = findHeight(node);
}
}
public void encodedInput(StringBuffer prefix) {
fullcode = fullcode + " , " + prefix;
}
//Method to get height
public int findHeight(HuffmanNode node) {
if (node == null) {
return -1;
}
int lefth = findHeight((HuffmanNode) node.left);
int righth = findHeight((HuffmanNode) node.right);
if (lefth > righth) {
return lefth + 1;
} else {
return righth + 1;
}
}
}
Other class I have:
class HuffmanNode extends HuffmanTree {
public HuffmanTree left;
public HuffmanTree right;
public HuffmanNode(HuffmanTree left, HuffmanTree right) {
super(left.frequency + right.frequency);
this.left = left;
this.right = right;
}
}
class HuffmanLeaf extends HuffmanTree {
public char value; // the character this leaf represents
public HuffmanLeaf(int frequency, char value) {
super(frequency);
this.value = value;
}
}
public class HuffmanTree implements Comparable<HuffmanTree> {
public int frequency; // the frequency of this tree
public HuffmanTree(int frequency) {
this.frequency = frequency;
}
public int compareTo(HuffmanTree tree) {
return frequency - tree.frequency;
}
}
You are doing
trees.offer(new HuffmanLeaf(charFreqs[x], (char) x));
and afterwards, you do:
HuffmanTree a = trees.poll();
HuffmanTree b = trees.poll();
// put into new node and re-insert into queue
trees.offer(new HuffmanNode(a, b));
So actually a or b might be instance of HuffmanLeaf
In that case,
(HuffmanNode) node.left
causes error since node.left is actually an instance of HuffmanLeaf
So here's the code that works.
// Method to get height
public int findHeight(HuffmanTree tree) {
if (tree == null) {
return -1;
}
if (tree instanceof HuffmanLeaf) {
return 1;
} else if (tree instanceof HuffmanNode) {
int lefth = findHeight(((HuffmanNode) tree).left);
int righth = findHeight(((HuffmanNode) tree).right);
if (lefth > righth) {
return lefth + 1;
} else {
return righth + 1;
}
} else {
return -1; // does not happen, you might want to raise exception.
}
}
You have to consider the both case when the actual instance of HuffmanTree is either HuffmanNode or HuffmanLeaf.
import java.util.*;
class Node
{
int data;
Node left , right;
public Node (int item)
{
data = item;
left = right = null;
}
}
class BinaryTree
{
public static Node root;
BinaryTree()
{
root = null;
}
public int largestBST(Node root)
{
MinMax m = largest(root);
return m.size;
}
public MinMax largest(Node root)
{
if(root == null)
{
return new MinMax();
}
MinMax leftMinMax = largest(root.left);
MinMax rightMinMax = largest(root.right);
MinMax m = new MinMax();
if(leftMinMax.isBST == false || rightMinMax.isBST == false || (leftMinMax.max > root.data) || (rightMinMax.min <= root.data))
{
m.isBST = false;
m.size = Math.max(leftMinMax.size , rightMinMax.size);
}
m.isBST = true;
m.size = leftMinMax.size + rightMinMax.size + 1;
m.min = root.left != null ? leftMinMax.min : root.data;//if left node is null take node as min or min of left
m.max = root.right != null ? rightMinMax.max : root.data;//if right node is null take node as max or max of right
return m;
}
class MinMax
{
int max,min;
boolean isBST;
int size;
MinMax()
{
max = Integer.MIN_VALUE;
min = Integer.MAX_VALUE;
isBST = false;
size = 0;
}
}
public static void main(String args[])
{
BinaryTree bt = new BinaryTree();
bt.root = new Node(25);
bt.root.left = new Node(18);
bt.root.right = new Node(50);
bt.root.left.left = new Node(19);
bt.root.left.right = new Node(20);
bt.root.right.left = new Node(35);
bt.root.right.right = new Node(60);
bt.root.right.left.right = new Node(40);
bt.root.right.left.left = new Node(20);
bt.root.right.right.left = new Node(55);
bt.root.right.right.right = new Node(70);
int size = bt.largestBST(root);
System.out.println("The size of largest BST is " + size);
}
}
Here the output should be 7 but instead it is showing the total number of nodes in the tree i.e. 11.
What's wrong with the code?
If you wish to find the maximum depth of the tree, then rewriting largestBST(Node root) like this will do:
public int largestBST(Node root)
{
if (root == null) {
return 0;
}
return 1 + Math.max(largestBST(root.left), largestBST(root.right));
}
What is happening here is that we return 1 + max(left subtree depth, right subtree depth). If the node doesn't exist, we return 0 to stop the recursion. This will return 4.
If by largest, you mean the subtree with the most nodes starting from the given root, regardless of the depth, then we can modify this solution to get the following:
public int largestBST(Node root)
{
if (root == null) {
return 0;
}
return Math.max(countNodes(root.left), countNodes(root.right));
}
public int countNodes(Node root)
{
if (root == null) {
return 0;
}
return 1 + countNodes(root.left) + countNodes(root.right);
}
As you can see, the recursion now happens in the countNodes() method, and largestBST() simply returns the max from left and right branches. The recursion follows the same principle as before. 0 is returned if a node doesn't exist, and we add 1 for each node that does exist. The result will be 7 now.
I have a tree and am trying to write a recursive method to find the smallest value in the tree however my method is not returning the smallest element in the tree, my output when I run my program is Minimum is: 24. Here is my code:
package weekFour;
public class MinTree {
static int min;
static Tree tree = new Tree( 24,
new Tree( 45,
null ,
new Tree(8, null , null) ) ,
new Tree ( 17,
new Tree (74 , null , null ) ,
null ) );
public static void main(String[] args){
MinTree mt = new MinTree();
System.out.println("Minimum is: " + mt.findMin(tree, Integer.MAX_VALUE));
}
public int findMin(Tree tree, int min){
if(tree.getVal() < min) {
min = tree.getVal();
}
Tree tree1 = tree.left();
if (tree1 != null) {
findMin(tree1, min);
}
Tree tree2 = tree.right();
if (tree2 != null) {
findMin(tree2, min);
}
return min;
}
}
class Tree {
private int val;
private Tree left, right;
public Tree(int val, Tree left, Tree right){
this.val = val;
this.left = left;
this.right = right;
}
public int getVal(){
return val;
}
public Tree left(){
return left;
}
public Tree right(){
return right;
}
}
Thanks for your time
In your findMin method, you don't capture the result of the recursive call...
Change:
Tree tree1 = tree.left();
if (tree1 != null) {
findMin(tree1, min);
}
Tree tree2 = tree.right();
if (tree2 != null) {
findMin(tree2, min);
}
To something like this:
Tree tree1 = tree.left();
if (tree1 != null) {
min = findMin(tree1, min);
}
Tree tree2 = tree.right();
if (tree2 != null) {
min = findMin(tree2, min);
}
You local min name = static variable's min name.
change it to get the right result. or do something like this =>
public int findMin(Tree tree, int min){
if(tree.getVal() < min) {
MinTree.min = tree.getVal();
}
Tree tree1 = tree.left();
if (tree1 != null) {
findMin(tree1, MinTree .min);
}
Tree tree2 = tree.right();
if (tree2 != null) {
findMin(tree2, MinTree .min);
}
return help.min;
}