import java.util.*;
class Node {
int data;
Node left;
Node right;
Node(int data) {
this.data = data;
left = null;
right = null;
}
}
public class Main {
public static void main(String[] args) {
Node root = new Node(2);
root.left = new Node(1);
root.right = new Node(4);
root.left.left = new Node(2);
root.left.right = new Node(1);
root.right.right = new Node(1);
root.right.right.left = new Node(7);
root.right.right.right = new Node(5);
// Function call
List<Integer> uniqueNodes = findUniquePattern(root);
// Printing the values of unique nodes
System.out.println(uniqueNodes.get(0) + " " +
uniqueNodes.get(1) + " " +
uniqueNodes.get(2));
}
// Function for counting total unique nodes
public static List<Integer> findUniquePattern(Node root) {
// Initializing hashmaps for tracking different patterns
Map<Integer, Integer> twoChild = new HashMap<>();
Map<Integer, Integer> oneChild = new HashMap<>();
Map<Integer, Integer> noChild = new HashMap<>();
// Function call for tracking the unique nodes
trackPattern(root, twoChild, oneChild, noChild);
// Returning the size of hashmaps, which represents unique nodes
return Arrays.asList(noChild.size(), oneChild.size(), twoChild.size());
}
// Helper function for inserting values in hashmaps and tracking pattern
public static void trackPattern(Node root, Map<Integer, Integer> twoChild,
Map<Integer, Integer> oneChild,
Map<Integer, Integer> noChild) {
if (root == null) {
return;
}
// When node have two child
if (root.left != null && root.right != null) {
// Insert the node into hashmap
twoChild.put(root.data, twoChild.getOrDefault(root.data, 0) + 1);
// Call recursion on left child
trackPattern(root.left, twoChild, oneChild, noChild);
// Call recursion on right child
trackPattern(root.right, twoChild, oneChild, noChild);
}
// When node is leaf node
else if (root.left == null && root.right == null) {
// Insert the node into hashmap
noChild.put(root.data, noChild.getOrDefault(root.data, 0) + 1);
}
// When node have one child
else {
oneChild.put(root.data, oneChild.getOrDefault(root.data, 0) + 1);
// If right child is not null, call recursion on right child
if (root.left != null) {
trackPattern(root.left, twoChild, oneChild, noChild);
}
// If left child is not null, call recursion on left child
if (root.right != null) {
trackPattern(root.right, twoChild, oneChild, noChild);
}
}
}
}