The other answers already gave a good solution to the question as you interpreted it. So I'm not going to repeat those.
Instead I'm going to see how much simpler things could be if you interpret the question a bit differently.
Nowhere in the question was there any mention of null beïng a valid child for a node. The question only speaks of internal and external nodes.
What happens if we think of an external node as a valid leaf node, and constrain an internal node to always contain 2 valid children, never null?
Let's start by defining 2 classes. An `InternalNode` and an `ExternalNode`. Now since an `InternalNode` has 2 children that could be either of those classes, let's also define a common superclass `Node` to be able to store the children properly. Since we're definately going to need to be able to see if a `Node` is a leaf node or not, let's make it easy for ourselves and also add a method `isLeaf()`.
public abstract class Node {
public abstract boolean isLeaf();
}
public class ExternalNode extends Node {
public ExternalNode(){
}
@Override
public boolean isLeaf() {
return true;
}
}
public class InternalNode extends Node {
private Node left;
private Node right;
public InternalNode(Node left, Node right) {
this.left = left;
this.right = right;
}
public Node getLeft(){
return left;
}
public Node getRight(){
return right;
}
@Override
public boolean isLeaf() {
return false;
}
}
Now that we have our basic Node classes let's look at how to actually solve our problem. There are 2 possible ways to do this now. One is to write a method externally like you did. One thing to note here though, is that only InternalNode has getters for child nodes. So this requires casting:
public static int strangeCount(Node node){
if(node.isLeaf()){
return 0;
}
InternalNode internal = (InternalNode) node;
return strangeCount(internal.getLeft()) +
strangeCount(internal.getRight()) +
(isWantedNode(internal)?1:0);
}
public static boolean isWantedNode(InternalNode node){
//Did you know java has an xor operator for booleans?
return node.getLeft().isLeaf() ^ node.getRight().isLeaf();
}
Alternatively we can also add a method to the `Node` classes to handle this cleaner (I'll only show the added methods for each class here):
public abstract class Node {
public abstract int strangeCount();
}
public class ExternalNode extends Node {
@Override
public int strangeCount() {
return 0;
}
}
public class InternalNode extends Node {
@Override
public int strangeCount() {
return strangeCount(getLeft()) +
strangeCount(getRight()) +
(isWantedNode()?1:0);
}
public boolean isWantedNode(){
//Did you know java has an xor operator for booleans?
return getLeft().isLeaf() ^ getRight().isLeaf();
}
}
Just a reminder: this entire answer only works if you do not allow null Nodes in the tree. It might not be applicable to how the actual question was intended to be solved. That's up to you to decide :)