Java Visitor Pattern

Sort by

recency

|

200 Discussions

|

  • + 0 comments

    I am getting the time limit exceeded notice for cases 9 through 13. My answers match, so the code is working as needed. I implemented ForkJoinTask and took the run time from 89 seconds to 25 seconds, per my IDE. However, it is still showing that it is taking too long. It recommends looking at the environment info, but I do not understand what I should do with the information on that page.

    I do not want the answer, but would not mind a hint of what classes or topics I should research to improve my code speed or performance.

    The code I am using, including the code already provided by HackerRank, is below. The solve method and TreeCreator class are my code.

    import java.util.; import java.util.concurrent.;

    enum Color { RED, GREEN }

    abstract class Tree {

    private int value;
    private Color color;
    private int depth;
    
    public Tree(int value, Color color, int depth) {
        this.value = value;
        this.color = color;
        this.depth = depth;
    }
    
    public int getValue() {
        return value;
    }
    
    public Color getColor() {
        return color;
    }
    
    public int getDepth() {
        return depth;
    }
    
    public abstract void accept(TreeVis visitor);
    

    }

    class TreeNode extends Tree {

    private ArrayList<Tree> children = new ArrayList<>();
    
    public TreeNode(int value, Color color, int depth) {
        super(value, color, depth);
    }
    
    public void accept(TreeVis visitor) {
        visitor.visitNode(this);
    
        for (Tree child : children) {
            child.accept(visitor);
        }
    }
    
    public void addChild(Tree child) {
        children.add(child);
    }
    

    }

    class TreeLeaf extends Tree {

    public TreeLeaf(int value, Color color, int depth) {
        super(value, color, depth);
    }
    
    public void accept(TreeVis visitor) {
        visitor.visitLeaf(this);
    }
    

    }

    abstract class TreeVis { public abstract int getResult(); public abstract void visitNode(TreeNode node); public abstract void visitLeaf(TreeLeaf leaf);

    }

    class SumInLeavesVisitor extends TreeVis { private int sum = 0;

    public int getResult() {
          //implement this
        return sum;
    }
    
    public void visitNode(TreeNode node) {
          //implement this
    }
    
    public void visitLeaf(TreeLeaf leaf) {
          //implement this
        sum += leaf.getValue();
    }
    

    }

    class ProductOfRedNodesVisitor extends TreeVis { private Long product = 1L; private int modulus = 1000000007;

    public int getResult() {
          //implement this
        return product.intValue();
    }
    
    public void visitNode(TreeNode node) {
          //implement this
        if (node.getColor() == Color.RED){
            product = (product * node.getValue()) % modulus;
    
            if (product == 0) product = 1L;
            else if (product < 0) product += modulus;
        }
    }
    
    public void visitLeaf(TreeLeaf leaf) {
          //implement this
        if (leaf.getColor() == Color.RED){
            product = (product * leaf.getValue()) % modulus;
    
            if (product == 0) product = 1L;
            else if (product < 0) product += modulus;
        }
    }
    

    }

    class FancyVisitor extends TreeVis { int evenSum = 0; int leafSum = 0;

    public int getResult() {
          //implement this
        return Math.abs(evenSum - leafSum);
    }
    
    public void visitNode(TreeNode node) {
        //implement this
        if (node.getDepth() % 2 == 0) evenSum += node.getValue();
    }
    
    public void visitLeaf(TreeLeaf leaf) {
        //implement this
        if (leaf.getColor() == Color.GREEN) leafSum += leaf.getValue();
    }
    

    }

    class TreeCreator extends RecursiveAction{ private final TreeNode parent; private final int parentIndex; private final ArrayList values; private final ArrayList colors; private final HashMap> edges; private final Set visited; private final ArrayList children;

    public TreeCreator(TreeNode parent, int parentIndex, ArrayList<Integer>
            children, ArrayList<Integer> values, ArrayList<Color>
            colors, HashMap<Integer, ArrayList<Integer>> edges, Set<Integer>
            visited) {
        this.parent = parent;
        this.parentIndex = parentIndex;
        this.values = values;
        this.colors = colors;
        this.edges = edges;
        this.visited = visited;
        this.children = children;
    }
    
    public void addChildren() {
        visited.add(parentIndex + 1);
        ArrayList<TreeCreator> tasks = new ArrayList<>();
    
        for (int childIndex : children) {
            int actualIndex = childIndex - 1;
            int depth = parent.getDepth() + 1;
            ArrayList<Integer> grandChildren = Solution.getChildren(actualIndex, edges, visited);
            Tree tempNode = (grandChildren != null) ? new TreeNode(values.
                    get(actualIndex), colors.get(actualIndex), depth) : new
                    TreeLeaf(values.get(actualIndex), colors.get(actualIndex),
                    depth);
    
            parent.addChild(tempNode);
    
            if (tempNode instanceof TreeNode) {
                tasks.add(new TreeCreator((TreeNode) tempNode, actualIndex, grandChildren, values, colors, edges, visited));
            }
        }
    
        if (!tasks.isEmpty()) {
            ForkJoinTask.invokeAll(tasks);
        }
    }
    
    @Override
    protected void compute() {
        addChildren();
    }
    

    }

    public class Solution {

    public static Tree solve() {
        Scanner input = new Scanner(System.in);
        int nodesNum = input.nextInt();
        input.nextLine();
        String[] valueStrings = input.nextLine().split(" ");
        String[] colorStrings = input.nextLine().split(" ");
        ArrayList<Integer> values = new ArrayList<>(nodesNum);
        ArrayList<Color> colors = new ArrayList<>(nodesNum);
        HashMap<Integer, ArrayList<Integer>> edges = new HashMap<>();
        Set<Integer> visited = Collections.synchronizedSet(new 
            HashSet<Integer>());
    
        Runnable valueConverter = () -> {
            for (int i = 0; i < nodesNum; i++) {
                values.add(Integer.parseInt(valueStrings[i]));
            }
        };
    
        Runnable colorConverter = () -> {
            for (int i = 0; i < nodesNum; i++) {
                colors.add((colorStrings[i].equals("0")) ? 
                Color.RED : Color.GREEN);
            }
        };
    
        Runnable edgeMapCreator = () -> {
            for (int i = 0; i < nodesNum - 1; i++) {
                int key = input.nextInt();
                int value = input.nextInt();
    
                if (edges.get(key) == null) {
                    ArrayList<Integer> temp = new ArrayList<>();
                    temp.add(value);
                    edges.put(key, temp);
                } else edges.get(key).add(value);
            }
        };
    
        Thread thread1 = new Thread(valueConverter);
        Thread thread2 = new Thread(colorConverter);
        Thread thread3 = new Thread(edgeMapCreator);
        thread1.start();
        thread2.start();
        thread3.start();
    
        while (thread1.isAlive() || thread2.isAlive() || thread3.isAlive()) {
            continue;
        }
    
        input.close();
    
        TreeNode rootNode = new TreeNode(values.get(0), colors.get(0), 0);
        ArrayList<Integer> children = getChildren(0, edges, visited);
    
        new TreeCreator(rootNode, 0, children, values, colors,
                    edges, visited).addChildren();
    
        return rootNode;
    }
    
    public static ArrayList<Integer> getChildren(int index, HashMap<Integer,
            ArrayList<Integer>> edges, Set<Integer> visited) {
        ArrayList<Integer> children = new ArrayList<>();
    
        for (int key : edges.keySet()) {
            if (key == index + 1) {
                for (int childIndex : edges.get(key)) {
                    if (!visited.contains(childIndex)) children.add(childIndex);
                }
            } else if (edges.get(key).contains(index + 1) && !visited
                    .contains(key)) {
                children.add(key);
            }
        }
    
        return ((children.isEmpty()) ? null : children);
    }
    
    public static void main(String[] args) {
          Tree root = solve();
        SumInLeavesVisitor vis1 = new SumInLeavesVisitor();
          ProductOfRedNodesVisitor vis2 = new ProductOfRedNodesVisitor();
          FancyVisitor vis3 = new FancyVisitor();
    
          root.accept(vis1);
          root.accept(vis2);
          root.accept(vis3);
    
          int res1 = vis1.getResult();
          int res2 = vis2.getResult();
          int res3 = vis3.getResult();
            }
    }
    
          System.out.println(res1);
         System.out.println(res2);
        System.out.println(res3);
    
  • + 0 comments

    class SumInLeavesVisitor extends TreeVis { private int sum = 0;

    public int getResult() {
        return sum;
    }
    
    public void visitNode(TreeNode node) {
        // Do nothing for non-leaf nodes
    }
    
    public void visitLeaf(TreeLeaf leaf) {
        sum += leaf.getValue();
    }
    

    }

    class ProductOfRedNodesVisitor extends TreeVis { private long product = 1; private final int MOD = 1000000007;

    public int getResult() {
        return (int) (product % MOD);
    }
    
    public void visitNode(TreeNode node) {
        if (node.getColor() == Color.RED) {
            product = (product * node.getValue()) % MOD;
        }
    }
    
    public void visitLeaf(TreeLeaf leaf) {
        if (leaf.getColor() == Color.RED) {
            product = (product * leaf.getValue()) % MOD;
        }
    }
    

    }

    class FancyVisitor extends TreeVis { private int sumNonLeafEvenDepth = 0; private int sumGreenLeaves = 0;

    public int getResult() {
        return Math.abs(sumNonLeafEvenDepth - sumGreenLeaves);
    }
    
    public void visitNode(TreeNode node) {
        if (node.getDepth() % 2 == 0) {
            sumNonLeafEvenDepth += node.getValue();
        }
    }
    
    public void visitLeaf(TreeLeaf leaf) {
        if (leaf.getColor() == Color.GREEN) {
            sumGreenLeaves += leaf.getValue();
        }
    }
    

    }

    public class Solution { private static int[] values; private static Color[] colors; private static Map> edges = new HashMap<>();

    public static Tree solve() {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
    
        values = new int[n];
        colors = new Color[n];
    
        for (int i = 0; i < n; i++) {
            values[i] = scanner.nextInt();
        }
    
        for (int i = 0; i < n; i++) {
            colors[i] = (scanner.nextInt() == 0) ? Color.RED : Color.GREEN;
        }
    
        for (int i = 0; i < n - 1; i++) {
            int u = scanner.nextInt() - 1;
            int v = scanner.nextInt() - 1;
    
            if (!edges.containsKey(u)) {
                edges.put(u, new HashSet<Integer>());
            }
            edges.get(u).add(v);
    
            if (!edges.containsKey(v)) {
                edges.put(v, new HashSet<Integer>());
            }
            edges.get(v).add(u);
        }
        scanner.close();
    
        return buildTree(0, 0);
    }
    
    private static Tree buildTree(int nodeIndex, int depth) {
        Set<Integer> neighbors = edges.get(nodeIndex);
    
        if (neighbors.isEmpty()) {
            return new TreeLeaf(values[nodeIndex], colors[nodeIndex], depth);
        }
    
        TreeNode node = new TreeNode(values[nodeIndex], colors[nodeIndex], depth);
    
        for (int neighbor : neighbors) {
            edges.get(neighbor).remove(nodeIndex);
            node.addChild(buildTree(neighbor, depth + 1));
        }
    
        return node;
    }
    
  • + 0 comments

    class SumInLeavesVisitor extends TreeVis { private int sum = 0;

    public int getResult() {
        return sum;
    }
    
    public void visitNode(TreeNode node) {
        // No action needed for internal nodes in this visitor
    }
    
    public void visitLeaf(TreeLeaf leaf) {
        sum += leaf.getValue();
    }
    

    }

    class ProductOfRedNodesVisitor extends TreeVis { private double product = 1;

    public int getResult() {
        return (int) product;
    }
    
    public void visitNode(TreeNode node) {
        increaseProduct(node);
    }
    
    public void visitLeaf(TreeLeaf leaf) {
        increaseProduct(leaf);
    }
    
    private void increaseProduct(Tree tree) {
        if (tree.getColor() == Color.RED) {
            product = (product * tree.getValue()) % (Math.pow(10, 9) + 7);
        }
    }
    

    }

    class FancyVisitor extends TreeVis { private int nonLeafNodeSum = 0; private int greenLeafSum = 0;

    public int getResult() {
        return Math.abs(nonLeafNodeSum - greenLeafSum);
    }
    
    public void visitNode(TreeNode node) {
        if (node.getDepth() % 2 == 0) {
            nonLeafNodeSum += node.getValue();
        }
    }
    
    public void visitLeaf(TreeLeaf leaf) {
        if (leaf.getColor() == Color.GREEN) {
            greenLeafSum += leaf.getValue();
        }
    }
    

    }

    public class Solution {

    public static Tree solve() {
        Scanner scan = new Scanner(System.in);
        int n = Integer.parseInt(scan.nextLine());
        String valuesLine = scan.nextLine();
        String colorsLine = scan.nextLine();
    
        String[] valuesStr = valuesLine.split(" ");
        int[] values = new int[n];
    
        for (int i = 0; i < n; i++) {
            values[i] = Integer.parseInt(valuesStr[i]);
        }
    
        String[] colorsStr = colorsLine.split(" ");
        byte[] colors = new byte[n];
    
        for (int i = 0; i < n; i++) {
            colors[i] = (byte) Integer.parseInt(colorsStr[i]);
        }
    
        Map<Integer, List<Integer>> adj = new HashMap<>();
        boolean[] visited = new boolean[n];
    
        for (int i = 0; i < n; i++) {
            adj.put(i, new ArrayList<Integer>());
        }
    
        while (scan.hasNextInt()) {
            int u = scan.nextInt() - 1;
            int v = scan.nextInt() - 1;
            adj.get(u).add(v);
            adj.get(v).add(u);
        }
    
        scan.close();
    
        return buildTree(0, 0, values, colors, adj, visited);
    }
    
    public static Tree buildTree(
        int index, int depth, int[] values, byte[] colors, Map<Integer, List<Integer>> adj, boolean[] visited
    ) {
        boolean isLeaf = true;
        visited[index] = true;
    
        Color color = colors[index] == 0 ? Color.RED : Color.GREEN;
        List<Integer> children = adj.get(index);
        TreeNode treeNode = new TreeNode(values[index], color, depth);
    
        for (int child : children) {
            if (!visited[child]) {
                isLeaf = false;
                Tree childNode = buildTree(child, depth + 1, values, colors, adj, visited);
                treeNode.addChild(childNode);
            }
        }
    
        if (isLeaf) {
            return new TreeLeaf(values[index], color, depth);
        } else {
            return treeNode;
        }
    }
    
  • + 0 comments

    what?!?

  • + 0 comments

    java solution with the supposed pre-existing classes

    public class Solution {
        static int n;
        static int[] values;
        static Color[] colors;
        static Map<Integer, Set<Integer>> edges;
    
        public static void main(String[] args) {
            Tree root = solve();
    
            SumInLeavesVisitor vis1 = new SumInLeavesVisitor();
            ProductRedNodesVisitor vis2 = new ProductRedNodesVisitor();
            FancyVisitor vis3 = new FancyVisitor();
    
            root.accept(vis1);
            root.accept(vis2);
            root.accept(vis3);
    
            System.out.println(vis1.getResult());
            System.out.println(vis2.getResult());
            System.out.println(vis3.getResult());
        }
        
         public static Tree solve() {
            Scanner sc = new Scanner(System.in);
            n = sc.nextInt();
    
            values = new int[n+1];
            for (int i = 1; i <= n; i++) {
                values[i] = sc.nextInt();
            }
    
            colors = new Color[n+1];
            for (int i = 1; i <= n; i++) {
                int c = sc.nextInt();
                colors[i] = (c == 0 ? Color.RED : Color.GREEN);
            }
    
            edges = new HashMap<>();
            for (int i = 1; i <= n; i++) edges.put(i, new HashSet<>());
            for (int i = 0; i < n-1; i++) {
                int u = sc.nextInt();
                int v = sc.nextInt();
                edges.get(u).add(v);
                edges.get(v).add(u);
            }
    
            sc.close();
            return buildTree(1, 0, -1); // root=1, depth=0, parent=-1
        }    
        
        private static Tree buildTree(int node, int depth, int parent) {
            Set<Integer> childs = edges.get(node);
            if(childs.size() == 1 && childs.contains(parent)){
                //es hoja
                return new TreeLeaf(values[node], colors[node], depth);
            } else {
                TreeNode tn = new TreeNode(values[node], colors[node], depth);
                for(int child : childs){
                    if(child != parent) {
                        tn.addChild(buildTree(child, depth+1, node));
                    }
                }
                return tn;
            }
        }
    }
    
    enum Color {RED, GREEN}
    
    abstract class Tree {
        private int value;
        private Color color;
        private int depth;
        
        public Tree(int value, Color color, int depth){
            this.value = value;
            this.color = color;
            this.depth = depth;
            
        }
        
        public int getValue(){ return value;}
        public Color getColor(){ return color;}
        public int getDepth(){ return depth;}
        
        public abstract void accept(TreeVis visitor);
    }
    
    class TreeNode extends Tree{
        private List<Tree> children = new ArrayList<>();
        
        public TreeNode(int value, Color color, int depth){
            super(value, color, depth);
        }
        
        public void accept(TreeVis visitor){
            visitor.visitNode(this);
            for(Tree child : children){
                child.accept(visitor);
            }
        }
        
        public void addChild(Tree child){ children.add(child); }
    }
    
    class TreeLeaf extends Tree{
        public TreeLeaf(int value, Color color, int depth){
            super(value, color, depth);
        }
        
        public void accept(TreeVis visitor){
            visitor.visitLeaf(this);
        }
    }
    
    interface TreeVis{
        int getResult();
        void visitNode(TreeNode tree);
        void visitLeaf(TreeLeaf tree);
    }
    
    class SumInLeavesVisitor implements TreeVis {
        private int sum = 0;
        
        public int getResult(){ return sum; }
        
        public void visitNode(TreeNode node){ /*no hace nada*/ }
        
        public void visitLeaf(TreeLeaf leaf){
            sum += leaf.getValue();
        }
    }
    
    class ProductRedNodesVisitor implements TreeVis {
        private long product = 1;
        private static final int MOD = 1000000007;
         
        public int getResult(){ return (int)(product % MOD); }
        
        public void visitNode(TreeNode node){ 
            if(node.getColor() == Color.RED)
                product = (product * node.getValue()) % MOD;
         }
        
        public void visitLeaf(TreeLeaf leaf) {
            if (leaf.getColor() == Color.RED) {
                product = (product * leaf.getValue()) % MOD;
            }
        }
    }
    
    class FancyVisitor  implements TreeVis {
        private int evenDepthNonLeafSum  = 0;
        private int greenLeafSum = 0;
         
        public int getResult(){ return (int)(Math.abs( evenDepthNonLeafSum - greenLeafSum)); }
        
        public void visitNode(TreeNode node){ 
            if(node.getDepth()  % 2 == 0)
                evenDepthNonLeafSum += node.getValue();
         }
        
        public void visitLeaf(TreeLeaf leaf) {
            if (leaf.getColor() == Color.GREEN) {
                greenLeafSum += leaf.getValue();
            }
        }
    }