Java Visitor Pattern

  • + 0 comments

    This is my take on this problem:

    1. Nowhere in the problem it is stated that one of the two nodes of an edge is 100% the parent. Which means, you cannot assume it.

    2. You can work yourself through construction level by level, with a queue. Dequeue the next potential parent, and enqueue all implemented children. Save all edges in an adjacent list, then implement this strategy.

    3. Mark all visited nodes! You don't want to accidentally attatch a parent as another child.

    4. Modulo needs clarification. You are expected to use it on every calculation for every node, and not on the final sum.

    This is my solution:

    class SumInLeavesVisitor extends TreeVis {
        private int sumInLeavesVisitor = 0;
        public int getResult() {
          	//implement this
            return sumInLeavesVisitor;
        }
    
        public void visitNode(TreeNode node) {
          	//implement this
        }
    
        public void visitLeaf(TreeLeaf leaf) {
          	//implement this
            sumInLeavesVisitor += leaf.getValue();
        }
    }
    
    class ProductOfRedNodesVisitor extends TreeVis {
        private int productOfRedNodesVisitor = 1;
        final private int mod = 1000000007;
        public int getResult() {
          	//implement this
            return productOfRedNodesVisitor;
        }
    
        public void visitNode(TreeNode node) {
          	//implement this
            if(node.getColor() == Color.RED)productOfRedNodesVisitor = (int)(((long)productOfRedNodesVisitor * node.getValue()) % mod);
        }
    
        public void visitLeaf(TreeLeaf leaf) {
          	//implement this
            if(leaf.getColor() == Color.RED)productOfRedNodesVisitor = (int)(((long)productOfRedNodesVisitor * leaf.getValue()) % mod);
        }
    }
    
    class FancyVisitor extends TreeVis {
        private int nonLeafValue = 0;
        private int leafValue = 0;
        public int getResult() {
          	//implement this
            int difference = leafValue - nonLeafValue;
            return Math.abs(difference);
        }
    
        public void visitNode(TreeNode node) {
        	//implement this
            if(node.getDepth() % 2 == 0)nonLeafValue += node.getValue();
        }
    
        public void visitLeaf(TreeLeaf leaf) {
        	//implement this
            if(leaf.getColor() == Color.GREEN)leafValue += leaf.getValue();
        }
    }
    
    public class Solution {
      
        public static Tree solve() {
            //read the tree from STDIN and return its root as a return value of this function
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            int[] nodeValues = new int[n];
            Color[] nodeColors = new Color[n];
            List<List<Integer>> adjList = new ArrayList<>();
            
            for(int i = 0; i < n; i++){
                nodeValues[i] = sc.nextInt();
                adjList.add(new ArrayList<Integer>());
            }
            for(int i = 0; i < n; i++){
                nodeColors[i] = sc.nextInt() == 0 ? Color.RED : Color.GREEN;
            }
            
            Tree[] treeNodes = new Tree[n];
            treeNodes[0] = new TreeNode(nodeValues[0], nodeColors[0], 0);
            Queue<Integer> parentQueue = new LinkedList<>();
            parentQueue.add(0);
            boolean[] visited = new boolean[n];
            visited[0] = true;
            
            for(int i = 0; i < n - 1; i++){
                int u = sc.nextInt() - 1;
                int v = sc.nextInt() - 1;
                adjList.get(u).add(v);
                adjList.get(v).add(u);
            }
            while(!parentQueue.isEmpty()){
                int parentIndex = parentQueue.poll();
                Tree parent = treeNodes[parentIndex];
                for(int childIndex : adjList.get(parentIndex)){
                    if(!visited[childIndex]){
                        Tree child;
                        if(adjList.get(childIndex).size() == 1){
                            child = new TreeLeaf(nodeValues[childIndex], nodeColors[childIndex], parent.getDepth() + 1);
                        }
                        else{
                            child = new TreeNode(nodeValues[childIndex], nodeColors[childIndex], parent.getDepth() + 1);
                        }
                        treeNodes[childIndex] = child;
                        visited[childIndex] = true;
                        parentQueue.add(childIndex);
                        ((TreeNode) parent).addChild(child);   
                    }
                }
            }
            return treeNodes[0];
            
        }