Java and C Solution using level order  (O(n))
Intuition\n Describe your first thoughts on how to solve this problem. \n\n# Approach\n Describe your approach to solving the problem. \n1. Arrays left, right, 
# Intuition\n<!-- Describe your first thoughts on how to solve this problem. -->\n\n# Approach\n<!-- Describe your approach to solving the problem. -->\n1. Arrays left, right, and remove:\n    - left[i]: Maximum height of the left subtree of node i.\n    - right[i]: Maximum height of the right subtree of node i.\n    - remove[i]: Tree height after removing the subtree rooted at node i.\n2. storeMaxDepth Method:\nCalculates and stores the maximum depth for each node\u2019s left and right subtrees.\n3. depthAfterRemove Method:\nCalculates the maximum height of the remaining tree if each node\u2019s subtree is removed.\n\n# Complexity\n- Time complexity:O(n)\n<!-- Add your time complexity here, e.g. $$O(n)$$ -->\n\n- Space complexity:O(n)\n<!-- Add your space complexity here, e.g. $$O(n)$$ -->\n\n# Code\n```java []\nclass Solution {\n    int[] left;\n    int[] right;\n    int[] remove;\n    public int[] treeQueries(TreeNode root, int[] queries) {\n        left = new int[100001];\n        right = new int[100001];\n        remove = new int[100001];\n        storeMaxDepth(root, 0);\n        depthAfterRemove(root, 0);\n        for (int i = 0; i < queries.length; i++) {\n            queries[i] = remove[queries[i]];\n        }\n        return queries;\n    }\n    private int storeMaxDepth(TreeNode root, int level) {\n        if (root == null) return level - 1;\n        int leftVal = storeMaxDepth(root.left, level + 1);\n        int rightVal = storeMaxDepth(root.right, level + 1);\n        left[root.val] = leftVal;\n        right[root.val] = rightVal;\n        return Math.max(leftVal, rightVal);\n    }\n    private void depthAfterRemove(TreeNode root, int level) {\n        if (root == null) return;\n        remove[root.val] = level;\n        depthAfterRemove(root.left, Math.max(right[root.val], level));\n        depthAfterRemove(root.right, Math.max(left[root.val], level));\n    }\n}\n```\n```C []\n#define MAX_NODES 100001\nint left[MAX_NODES];\nint right[MAX_NODES];\nint removeDepth[MAX_NODES];\nint storeMaxDepth(struct TreeNode* root, int level);\nvoid depthAfterRemove(struct TreeNode* root, int level);\n\nint* treeQueries(struct TreeNode* root, int* queries, int queriesSize, int* returnSize) {\n    *returnSize = queriesSize;\n    int* result = (int*)malloc(queriesSize * sizeof(int));\n    for (int i = 0; i < MAX_NODES; i++) {\n        left[i] = right[i] = removeDepth[i] = 0;\n    }\n    storeMaxDepth(root, 0);\n    depthAfterRemove(root, 0);\n    for (int i = 0; i < queriesSize; i++) {\n        result[i] = removeDepth[queries[i]];\n    }\n    return result;\n}\n\nint storeMaxDepth(struct TreeNode* root, int level) {\n    if (root == NULL) return level - 1;\n    int leftVal = storeMaxDepth(root->left, level + 1);\n    int rightVal = storeMaxDepth(root->right, level + 1);\n    left[root->val] = leftVal;\n    right[root->val] = rightVal;\n    return (leftVal > rightVal) ? leftVal : rightVal;\n}\n\nvoid depthAfterRemove(struct TreeNode* root, int level) {\n    if (root == NULL) return;\n    removeDepth[root->val] = level;\n    depthAfterRemove(root->left, (right[root->val] > level) ? right[root->val] : level);\n    depthAfterRemove(root->right, (left[root->val] > level) ? left[root->val] : level);\n}\n```
['Java']