Find sum of odd keys in Binary Search Tree - java

I need to find the sum of odd keys in a Binary Search Tree
public int OddKeys(Node root) {
if (root == null) {
return 0;
}
int value = 0;
if (root.key.compareTo(value) % 2 == 0) {
return value + OddKeys(root.left) + OddKeys(root.right);
}
return value + OddKeys(root.left) + OddKeys(root.right);
}
I am unable to run this because I am confused on how to set "if (root.key.compareTo(value) % 2 == 0)". What would be the correct way to check if the keys are odd or not.

I don't know what that compareTo(0) is hoping to do. If we assume that your keys are simple integers, something like this might be what you're trying to get to:
public int OddKeys(Node root) {
if (root == null)
return 0;
int value = (root.key % 2 == 0)? 0 : 1;
return value + OddKeys(root.left) + OddKeys(root.right);
}

Related

Comparing and finding an ArrayList with the longest length

I am solving a task linked to the Collatz Problem. I have created a method that produces 1 from any starting number:
public static void sequence(int value)
{
ArrayList<Integer> calc = new ArrayList<Integer>();
calc.add(value);
while(value != 1)
{
if(value % 2 == 0)
{
value = value / 2;
}
else if(value % 2 != 0)
{
value = (value * 3) + 1;
}
calc.add(value);
if(value == 1 )
{
System.out.println(calc);
}
}
}
public static void main(String[] args) {
for(int x = 1000000; x > 0; x--)
{
sequence(x);
}
}
}
The next part of my task is finding a method which will find the longest Collatz sequence below 1,000,000.
I came up with several solutions such as the one below..of course none of them worked.
while(value != 1)
{
if(value % 2 == 0)
{
value = value / 2;
}
else if(value % 2 != 0)
{
value = (value * 3) + 1;
}
calc1.add(value);
if(calc1.size() > calc2.size())
{
calc2 = calc1;
}
}
System.out.println(calc2);
}
Could anyone please help and guide me to finding the correct methods for finding the longest Collatz sequence using the comparison of 2 or more ArrayLists. If there are better options than the use of an ArrayList I more than welcome these methods.
Thanks.
You need to maintain a maxList which will get updated with the longest sequence.
You can either pass it to your calc() method in each call or declare it as a Class variable for using it on top of both calc() and main() methods.
// to update the max list
maxList = (list.size() > maxList.size()) ? list : maxList;
At the end just print the results
System.out.println(maxList.size());
System.out.println(maxList);
Update: You need to figure out efficient ways to pass numbers in the calc() method.
It will throw java.lang.OutOfMemoryError for large input.

How can I change my code below to avoid the unexpected type error (required : variable; found: value)?

1.The fifth line of my code below returns an unexpected type error where a variable is required but a value found.
2.The code is a to check if a number n is Prime or not using a while loop.
public boolean primeNumberCheck(int n)
{
int divisionNumber = 2;
boolean primeCheck = true;
while (divisionNumber < n)
{
if (n%divisionNumber = 0)
{
primeCheck = true;
divisionNumber = n;
}
else
{
primeCheck = false;
}
divisionNumber++;
}
return primeCheck;
}
= is the assignment operator. n%divisionNumber returns a value, and you cannot assign a value to another value. So you get that error.
You need to compare the values using the == operator. So, you should do:
if (n%divisionNumber == 0)
Apart from the answers here , one more tip which I follow is doing :
if (0 == n%divisionNumber) rather than if (n%divisionNumber = 0).
this ensures that I haven't missed one "=" sign.
This is not an answer, just a more optimized algorithm based on Primality test on WikiPedia
public boolean primeNumberCheck(int n) {
// exclude numbers with divisor 2 or 3
if (n % 2 == 0) {
return false;
}
if (n % 3 == 0) {
return false;
}
// all integers can be expressed as (6k + i) for some integer k and
// for i = −1, 0, 1, 2, 3, or 4;
// 2 divides (6k + 0), (6k + 2), (6k + 4); and 3 divides (6k + 3).
// so we only have to test numbers of the form 6k +- 1
int k = 1;
int i = -1;
// we only need to check candidates up to SQRT(n)
double sqrtN = Math.Sqrt(n);
int candidateDivisor = getCandidateDivisor(k, i);
while (candidateDivisor < sqrtN) {
if (n % candidateDivisor == 0) {
return false;
}
// flip i between -1 and 1
i = -i;
// when i flips back to -1, increment k
if (i < 0) {
k++;
}
candidateDivisor = getCandidateDivisor(k, i);
}
return true;
}
private int getCandidateDivisor(k, i) {
return (6 * k) + i;
}
DISCLAIMER: I have not tested this code

Search if there exist a subset that its sum equals the goal then prints it

I am trying to find if there exist a subset that its sum equals the goal then prints it. I am new in java and recursion is a bit confusing sometimes
void sumOfSubsets(int n, int[] w, int W) {
if (W == 0)
return;
if ((W < 0) || (n < 0))
return;
if (W == 0) {
System.out.print(w[n] + " ");
return;
}
sumOfSubsets(n - 1, w, W);
}
In general recursion becomes less confusing if you ask yourself:
What's a very simple situation that has an obvious answer; and
How can I make a non-simple situation into a simple one
In your case the answer are:
if the subset is empty, then only a target sum of 0 satisfies the condition
if the subset isn't empty, check if the set without the first item has a subset that equals the sum, or the sum minus the first item
Translating those answers to code:
boolean hasSumEqualTo(List<Integer> list, int sum) {
if (list.isEmpty())
return sum == 0;
int first = list.remove(0);
return hasSumEqualTo(list, sum) || hasSumEqualTo(list, sum - first);
}
Or, using arrays:
boolean hasSumEqualTo(int i, int[] list, int sum) {
if (i == list.length)
return sum == 0;
return hasSumEqualTo(i + 1, list, sum) || hasSumEqualTo(i + 1, list, sum - list[i]);
}
If you just want to print all subsets:
void printSubsetsThatSumTo(String current, List<Integer> list, int sum) {
if (list.isEmpty()) {
if (sum == 0)
System.out.println(current);
} else {
int first = list.remove(0);
printSubsetsThatSumTo(current, list, sum);
printSubsetsThatSumTo(current + " " + first, list, sum - first);
}
}
In all cases the pattern is exactly the same.

Find number of occurrences of digits from 1 to N without using loop

For example, n=11 means, then the map should have 0-1, 1-4, 2-1, 3-1, 4-1, 5-1, 6-1, 7-1, 8-1, 9-1
public void countDigits(int n, Map map) {
while (n != 0) {
int d = n%10;
n /= 10;
map.put(d,map.get(d)++);
}
return result;
}
Other than the above method.
I want to get all the digit count from 1 to N.
Your code isn't compiles at all. Try replace map.put(d,map.get(d)++); with
Integer tmp = (Integer)map.get(d);
if(tmp == null) tmp = 0;
tmp++;
map.put(d,tmp);

Find sum of nodes height in a binary tree recursively

How to find sum of node's height in a binary tree recursively?
Example:
public int totalHeight() {
return totalHeight(root);
}
private int totalHeight(BinaryNode<AnyType> n) {
int totalHeight = 0;
if (n.left == null && n.right == null)
return totalHeight;
if (n.left != null && n.right != null)
return totalHeight + 1
+ Math.max(totalHeight(n.left), totalHeight(n.right));
if (n.left != null)
return totalHeight + 1 + Math.max(totalHeight(n.left), -1);
if (n.right != null)
return totalHeight + 1 + Math.max(-1, totalHeight(n.right));
return totalHeight;
}
I have tried this, but it only get the height of the tree instead of sum of all node's height.
I feel difficult to track the counter in recursion, it seems that the totalHeight set to 0 every recursive call. This is not good.
A simple version would be to do a two-pass process where you first record for each node the height it is at, and then iterate through the nodes to sum them up. This method can be made recursive, but it is easy to do it in just one pass by summing as you calculate the height.
public static int totalHeightSum = 0;
private int calculateHeightAndAdd ( Node n )
{
if ( n == null )
return 0;
int leftHeight = calculateHeightAndAdd ( n.left );
int rightHeight= calculateHeightAndAdd ( n.right);
int myHeight = 1 + Math.max ( leftHeight, rightHeight );
totalHeightSum += myHeight;
return myHeight;
}
Recurcively find height of each node and keep adding to a static variable. Alternately, you could memorize the height and store in each node and then do another recursion to add them up.
The recursion should return the height of the node n and not the total heights of each of the nodes in the subtree.
Given your implementation of the height of a node, let's simply call it height(BinaryNode<?>), you can:
if you have access to all the nodes in a collection:
int sumHeight(List<BinaryNode<?>> nodes) {
int sum = 0;
for (BinaryNode<?> node: nodes) {
sum += height(node);
}
return sum;
}
if you only have access to the nodes in a tree structure:
int sumHeight(BinaryNode<?> node) {
if (node == null) return 0;
return height(node) + sumHeight(node.left) + sumHeight(node.right);
}
It would be interesting to see if there're algo's that can do the calculation in one recursion (maybe some backtracking algo?).
Ok. I have come out a solution.
a) if n == null return 0
b) if n.left == null && n.right == null return 0
c) the total height is total height of left + total height of right + the height of it self
the height of itself is:
1) if left side is larger, then total height of left minus total height of left's left
2) if right side is larger, then total height of right minus total height of right's right
public int totalHeight() {
return totalHeight(root);
}
private int totalHeight(BinaryNode<AnyType> n) {
if (n == null)
return 0;
else if (n.left == null && n.right == null)
return 0;
else
return totalHeight(n.left)
+ totalHeight(n.right)
+ (totalHeight(n.left) > totalHeight(n.right) ? totalHeight(n.left)
- (n.left == null ? 0 : totalHeight(n.left.left))
: totalHeight(n.right)
- (n.right == null ? 0
: totalHeight(n.right.right))) + 1;
}
I am assuming you are not updating heights during insertion.
Solution:
I would traverse through the tree in a inorder way. So I first declare root.height=0.
And then say
BinaryNode right;
BinaryNode left;
BinaryNode parent;
static int level;
int height;
if(left!=null)
{
left.height=left.parent.height+1;
level=level+left.height;
left.yourMethod();
}
if(right!=null)
{
right.height= right.parent.height+1;
level=level+right.height;
right.yourMethod();
}
So you will now have level that stores all the heights.
Alternative method can be Breadth first search traversal using a queue, but the answer would be the same.
Hope this helps.
void addHeights(class tree* root, int depth, int& sum)
{
if(root)
{
addHeights(root->left, depth+1, sum);
addHeights(root->right, depth+1, sum);
sum += depth;
}
}
public int sum(){
return sum(root);
}
private int sum(BinaryNode <?> n){
if(n == null)
return 0;
else
return n.data + sum(n.left) + sum(n.right);
}
I need more data to assess your code though I am assuming that you called the data inside the node "data".
So if the node is null it means you have reached the end of the tree and returns 0. Otherwise it takes the data and traverses towards the left then to the right. With each recursion they are being added until they are no more nodes left to be added.
private int maxHeight(BinaryNode<AnyType> n) {
if (n ! = null) return 0;
int leftheight = maxHeight(n.left);
int rightheight = maxHeight(n.right);
return (leftheight > rightheight) ? leftheight + 1 : rightheight + 1;
}
So far you have known the 4 cases to count the height
The essence is to continue to go left or right node if the left child or the right child exist.
if exist, return 1.
The counting function goes in the last statement. That is to get the largest height counted.
The main course is to get familiar with recursion and the programming stack when the method is working.

Categories