# Definition for a binary tree node.
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def removeLeafNodes(self, root: TreeNode, target: int) -> TreeNode:
if not root:
return None
root.left = self.removeLeafNodes(root.left, target)
root.right = self.removeLeafNodes(root.right, target)
if not root.left and not root.right and root.val == target:
return None
return root
// Definition for a binary tree node.
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
class Solution {
public:
TreeNode* removeLeafNodes(TreeNode* root, int target) {
if (!root) return nullptr;
root->left = removeLeafNodes(root->left, target);
root->right = removeLeafNodes(root->right, target);
if (!root->left && !root->right && root->val == target) {
delete root;
return nullptr;
}
return root;
}
};
// Definition for a binary tree node.
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
class Solution {
public TreeNode removeLeafNodes(TreeNode root, int target) {
if (root == null) return null;
root.left = removeLeafNodes(root.left, target);
root.right = removeLeafNodes(root.right, target);
if (root.left == null && root.right == null && root.val == target) {
return null;
}
return root;
}
}
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @param {number} target
* @return {TreeNode}
*/
var removeLeafNodes = function(root, target) {
if (!root) return null;
root.left = removeLeafNodes(root.left, target);
root.right = removeLeafNodes(root.right, target);
if (!root.left && !root.right && root.val === target) {
return null;
}
return root;
};
Given the root of a binary tree and an integer target
, remove all leaf nodes from the tree that have the value target
. If, after removing such leaves, new leaves are formed with the value target
, remove those as well. Repeat this process until no more leaves with value target
exist.
You must return the root of the modified tree. If the entire tree is deleted, return null
.
target
are integers.At first glance, this problem seems similar to simply removing leaves with a certain value. However, the twist is that removing leaves may create new leaves that also need to be checked and possibly removed. This recursive aspect means we must process the tree in a way that checks all possible leaves, even those that become leaves only after earlier deletions.
A brute-force approach might involve repeatedly traversing the tree and removing target-valued leaves until none remain, but this would be inefficient. Instead, we can use recursion to process the tree from the bottom up, always ensuring that by the time we consider a node, its children have already been processed.
This leads to the realization that a post-order traversal is ideal: we visit the left and right children before deciding whether to remove the current node.
We solve this problem using recursion and post-order traversal. Here's the step-by-step process:
null
, return null
. This handles empty subtrees.
root.left
and root.right
. Update the current node's left and right pointers with the results.
left
and right
are null
) and its value is equal to target
.
null
to delete this node.
This approach ensures that all "waves" of leaf removal are handled in a single bottom-up traversal, making it efficient and elegant. No additional data structures are needed, and we modify the tree in-place.
Let's use the following tree as an example, with target = 2
:
1 / \ 2 3 / \ 2 4
Step-by-step:
Final tree:
1 \ 3 \ 4
The key insight to this problem is recognizing that removing leaves can create new leaves, so a bottom-up (post-order) approach is essential. By processing children before their parent, we ensure that all necessary nodes are considered for removal in a single traversal. The recursive solution is efficient, elegant, and easy to implement, making use of the natural structure of binary trees and recursion.