Reputation: 37
Need to find the node with the maximum sum of children and itself. The Input format :
Line 1 : Elements in level order form separated by space (as per done in class). Order is -
Root_data, n (No_Of_Child_Of_Root), n children, and so on for every element
Output format : Node with maximum sum.
It returns correct answers but if you run the code by uncommenting the print statement you can see that the max sum is altered even though the current sum is less than the max sum.
public class Solution {
/* TreeNode structure
*
* class TreeNode<T> {
T data;
ArrayList<TreeNode<T>> children;
TreeNode(T data){
this.data = data;
children = new ArrayList<TreeNode<T>>();
}
}*/
public static TreeNode<Integer> maxSumNode(TreeNode<Integer> root){
// Write your code here
return maxSumNode(root, 0);
}
public static TreeNode<Integer> maxSumNode(TreeNode<Integer> root, int maxSum){
if(root.children.size() == 0){
return null;
}
TreeNode<Integer> maxNode = null;
int tempSum = root.data;
for(int i = 0 ; i < root.children.size() ; ++i){
tempSum += root.children.get(i).data;
}
if(tempSum > maxSum){
maxSum = tempSum;
maxNode = root;
}
//System.out.println("MaxNum now for "+root.data+" is: "+ maxSum);
for(int i = 0 ; i < root.children.size() ; ++i){
TreeNode<Integer> temp = maxSumNode(root.children.get(i), maxSum);
if(temp == null){
continue;
}
if(temp != null){
maxNode = temp;
}
}
return maxNode;
}
}
for example if i give the input: 5 3 1 2 3 1 15 2 4 5 1 6 0 0 0 0
I get the output correctly but the maxSum is weird:
Upvotes: 0
Views: 1008
Reputation: 1
Please check the below code for a simple solution.
public static int maxSum;
public static TreeNode<Integer> resNode;
public static TreeNode<Integer> maxSumNode(TreeNode<Integer> root){
maxSum=0;
helper(root);
return resNode;
}
public static void helper(TreeNode<Integer> root){
if(root==null){
return;
}
int currSum = root.data;
int count = root.children.size();
for (int i = 0; i < count; i++){
currSum += root.children.get(i).data;
helper(root.children.get(i));
}
if (currSum > maxSum){
resNode = root;
maxSum = currSum;
}
return;
}
Upvotes: 0
Reputation: 2576
Your problems:
Possible Solutions:
As parameter you could pass some class that contains the number. The reference itself changes (pass-by-value), but the addressed object always stays the same. So you always read/write on the same number.
Or you could have a member variable (static or non-static) but be really careful about access.
And third, you could use a statistics map or priority queue where ALL results are added, and when all is done, you choose the max.
The parameter solution is the easiest, safest and most efficient. The static is even easier, but disastrously unsafe, if maxSumNode gets run multiple times simultaneuosly. Last one is easy but not efficient.
/UPDATE:
Here's an example for solution #1. And a test. This has lots of additional code to show the different styles that can be implemented.
package stackoverflow;
import java.util.ArrayList;
public class MaxSumNode {
/**
* This is a partial implementation of the real TreeNode class, for local implementation only.
* Remove when you have accedd to the real TreeNode class.
*/
private static class TreeNode<T> {
T data;
ArrayList<TreeNode<T>> children;
public TreeNode(final T pData) {
this.data = pData;
children = new ArrayList<>();
}
public TreeNode<T> addChild(final TreeNode<T> pChild) {
if (children == null) children = new ArrayList<>();
children.add(pChild);
return pChild; // used for builder syntax
}
}
/**
* This is our class that contains the maximum and some additional infos (the max Node itself for example).
* This is private because it will not be used outside this class.
*/
private static class CounterReference<T> {
public int nodeSum = 0;
public T node = null;
public CounterReference() {}
}
public enum Mode {
ROOT_ONLY, ALL_LEVELS, ONLY_LEVEL_ONE, LEVEL_ONE_AND_BELOW
}
/**
* Public method that returns calculations of a pre-set mode
*/
public static CounterReference<TreeNode<Integer>> maxSumNode(final TreeNode<Integer> root) {
return maxSumNode(root, Mode.ALL_LEVELS);
}
/**
* Our only public 'intelligent' function, i.e. apart from the 2 simple helper functions.
* Here we set up for the calculations, and decide what range we actually want to consider in out calculations.
*/
public static CounterReference<TreeNode<Integer>> maxSumNode(final TreeNode<Integer> root, final Mode pMode) {
final CounterReference<TreeNode<Integer>> cr = new CounterReference<>();
// 4 different cases, depending on what you need. select ONE of those, comment out the rest
switch (pMode) {
case ROOT_ONLY: { // case 1: this case ONLY checks the root (level-0) element
checkNode(root, cr, false);
break;
}
case ALL_LEVELS: { // case 2: this case checks ALL elements, on ANY level
checkNode(root, cr, true);
break;
}
case ONLY_LEVEL_ONE: { // case 3: this case only checks level-1 elements (no root element, no child-children
if (root != null && root.children != null && root.children.size() > 0) {
for (final TreeNode<Integer> cs : root.children) {
checkNode(cs, cr, false);
}
}
break;
}
case LEVEL_ONE_AND_BELOW: { // case 4: this case checks level-1 elements and down wards, effectively leaving out the root element
if (root != null && root.children != null && root.children.size() > 0) {
for (final TreeNode<Integer> cs : root.children) {
checkNode(cs, cr, true);
}
}
break;
}
default:
throw new IllegalArgumentException("Unknown Mode '" + pMode + "'!");
}
return cr;
}
/**
* This node checks given Node and updates CounterReference if needed.
* This is private, because this method is only used by {@link #maxSumNode(TreeNode)} and will not be used outside this class
*/
private static void checkNode(final TreeNode<Integer> pNode, final CounterReference<TreeNode<Integer>> pCR, final boolean pRecursive) {
if (pNode == null) return;
final int sum = getWeightOfNodeAndDirectChildren(pNode);
// compare local result with global result
if (sum > pCR.nodeSum) {
// we found a new max, so update counter
pCR.nodeSum = sum;
pCR.node = pNode;
}
// maybe do a recursive check of children and sub-children and sub-sub-children etc
if (pRecursive && pNode.children != null && pNode.children.size() > 0) {
for (final TreeNode<Integer> childNode : pNode.children) {
checkNode(childNode, pCR, pRecursive);
}
}
}
/*
* Our helper methods, to make the above code easier
*/
public static int getWeightOfNodeAndDirectChildren(final TreeNode<Integer> pNode) {
if (pNode == null) return 0;
if (pNode.data == null) return 0;
int sum = 0;
sum += getWeightOfNode(pNode);
if (pNode.children != null && pNode.children.size() > 0) {
for (final TreeNode<Integer> childNode : pNode.children) {
sum += getWeightOfNode(childNode);
}
}
return sum;
}
public static int getWeightOfNode(final TreeNode<Integer> root) {
if (root == null) return 0;
if (root.data == null) return 0;
return root.data.intValue();
}
/**
* Our test method
*/
public static void main(final String[] args) {
final TreeNode<Integer> root = new TreeNode<>(Integer.valueOf(3));
root.addChild(new TreeNode<>(Integer.valueOf(5)));
final TreeNode<Integer> right = root.addChild(new TreeNode<>(Integer.valueOf(7)));
right.addChild(new TreeNode<>(Integer.valueOf(13)));
final TreeNode<Integer> rightRight = right.addChild(new TreeNode<>(Integer.valueOf(17)));
right.addChild(new TreeNode<>(Integer.valueOf(19)));
rightRight.addChild(new TreeNode<>(Integer.valueOf(23)));
rightRight.addChild(new TreeNode<>(Integer.valueOf(29)));
final TreeNode<Integer> left = root.addChild(new TreeNode<>(Integer.valueOf(11)));
left.addChild(new TreeNode<>(Integer.valueOf(31)));
final TreeNode<Integer> leftLeft = left.addChild(new TreeNode<>(Integer.valueOf(37)));
leftLeft.addChild(new TreeNode<>(Integer.valueOf(41)));
leftLeft.addChild(new TreeNode<>(Integer.valueOf(43)));
System.out.println("The tree:");
printNode(root, 0);
System.out.println();
System.out.println("The calculation modes:");
for (final Mode mode : Mode.values()) {
System.out.println("\tMode: " + mode);
final CounterReference<TreeNode<Integer>> result = maxSumNode(root, mode);
if (result == null || result.node == null) {
System.out.println("\n\n0.o NOO!11!! We do NOT havea result!");
} else {
System.out.println("\t\tNode " + result.node.data.intValue() + " with max " + result.nodeSum);
}
}
System.out.println("All done, exiting...");
}
private static void printNode(final TreeNode<Integer> pRoot, final int pDepth) {
if (pRoot == null) return;
for (int i = 0; i < pDepth; i++) {
System.out.print("\t");
}
System.out.println(pRoot.data);
if (pRoot.children != null && pRoot.children.size() > 0) {
for (final TreeNode<Integer> c : pRoot.children) {
printNode(c, pDepth + 1);
}
}
}
}
// UPDATE:
Fixed a mistake inside checkNode()
replaced if ... return
with if ... {}
because early return would prevent check of children, even though they might, on some deeper levels, find a new max.
Upvotes: 1