C++ 100%, Java 100%, Javascript 100%, C# 100%, recursive delete
Here\'s slightly modified recursive delete node from a tree function.  Bottom up approach, return either null or root and assign returned value to its original 
Here\'s slightly modified recursive *delete node from a tree* function.  Bottom up approach, return either `null` or `root` and assign returned value to its original location.\n\nThen there\'s *collect* logic: if parent of the current node is not deleted and node itslef is not a node to delete, add this node to the result collection.\n\n*Having class level variables instead of passing them down the call stack reduces time almost by 25% percent for C#.*\n\nC++ - 36ms\n```\npublic:\n    vector<TreeNode*> delNodes(TreeNode* root, vector<int>& to_delete) {\n        delSet = unordered_set<int>(to_delete.begin(), to_delete.end());\n        deleteNodes(root, nullptr);\n        return result;\n    }\nprivate:\n    TreeNode* deleteNodes(TreeNode* root, TreeNode* parent) {\n        if (root == nullptr) return nullptr;\n        auto current = delSet.count(root->val) ? nullptr : root;\n        if (parent == nullptr && current != nullptr) result.push_back(root);\n        root->left = deleteNodes(root->left, current);\n        root->right = deleteNodes(root->right, current);\n        return current;\n    }\n    unordered_set<int> delSet;\n    vector<TreeNode*> result;\n```\n\nJava - 38ms\n```\nSet<Integer> delSet;\nList<TreeNode> result = new ArrayList<>();\npublic List<TreeNode> delNodes(TreeNode root, int[] to_delete) {\n    delSet = Arrays.stream(to_delete).boxed().collect(Collectors.toSet());\n    deleteNodes(root, null);\n    return result;\n}\n\nTreeNode deleteNodes(TreeNode root, TreeNode parent) {\n    if (root == null) return null;\n    TreeNode current = delSet.contains(root.val) ? null : root;\n    if (parent == null && current != null) result.add(root);\n    root.left = deleteNodes(root.left, current);\n    root.right = deleteNodes(root.right, current);\n    return current;\n}\n```\n\nJavascript - 68ms\n```\nvar delNodes = function(root, to_delete) {\n    const delSet = to_delete.reduce((obj, item) => { obj[item] = item; return obj; }, {});\n    const result = [];\n    deleteNodes = (root, parent) => {\n        if (!root) return null;\n        const current = delSet[root.val] ? null : root;\n        if (!parent && current) result.push(current);\n        root.left = deleteNodes(root.left, current);\n        root.right = deleteNodes(root.right, current);\n        return current;\n    };\n    deleteNodes(root);\n    return result;\n};\n```\n\nC#\n\n```\nIList<TreeNode> result = new List<TreeNode>();\nHashSet<int> delSet;\npublic IList<TreeNode> DelNodes(TreeNode root, int[] to_delete) {\n    delSet = new HashSet<int>(to_delete);\n    delete(root, null);\n    return result;\n}\n\nTreeNode delete(TreeNode root, TreeNode parent) {\n    if (root == null) return null;\n\n    var current = delSet.Contains(root.val) ? null : root;\n    root.left = delete(root.left, current);\n    root.right = delete(root.right, current);\n\n    if (parent == null && current != null) result.Add(root);\n    return current;\n}\n```
['Recursion', 'C', 'Java', 'JavaScript']