1325. Delete Leaves With a Given Value**
https://leetcode.com/problems/delete-leaves-with-a-given-value/
题目描述
Given a binary tree root and an integer target, delete all the leaf nodes with value target.
Note that once you delete a leaf node with value target, if it’s parent node becomes a leaf node and has the value target, it should also be deleted (you need to continue doing that until you can’t).
Example 1:
Input: root = [1,2,3,2,null,2,4], target = 2
Output: [1,null,3,null,4]
Explanation: Leaf nodes in green with value (target = 2) are removed (Picture in left).
After removing, new nodes become leaf nodes with value (target = 2) (Picture in center).
Example 2:
Input: root = [1,3,3,3,2], target = 3
Output: [1,3,null,null,2]
Example 3:
Input: root = [1,2,null,2,null,2], target = 2
Output: [1]
Explanation: Leaf nodes in green with value (target = 2) are removed at each step.
Example 4:
Input: root = [1,1,1], target = 1
Output: []
Example 5:
Input: root = [1,2,3], target = 1
Output: [1,2,3]
Constraints:
1 <= target <= 1000
- Each tree has at most
3000
nodes. - Each node’s value is between
[1, 1000]
.
C++ 实现 1
本题需要注意第三个 example 中显示的结果, 如果删去左右孩子后, 节点自身此时也成了根节点并且值和 target
相等时, 那么节点自身也要被删除.
下面代码看起来逻辑好多, 但实际上主要是后序遍历. 递归到底的情况是, 如果节点本身为空, 或者左右孩子为空, 并且自身的值和 target
相等, 那么返回 nullptr
. 遍历完左右子树后, 如果左右孩子为根节点并且值等于 target
时, 需要将左右孩子置为 nullptr
. 如果此时 root
本身也成了叶子节点并且值等于 target, 那么最终返回的还是 nullptr
.
另外, 下面这种调用 root->left->left
, 即考虑了 grandson 的代码, 在 1315. Sum of Nodes with Even-Valued Grandparent** 也出现过. 可以考虑相互对比看看.
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
private:
TreeNode* postOrder(TreeNode *root, int target) {
if (!root || (!root->left && !root->right && root->val == target)) return nullptr;
root->left = postOrder(root->left, target);
root->right = postOrder(root->right, target);
if (root->left) {
if (!root->left->left && !root->left->right && root->left->val == target)
root->left = nullptr;
}
if (root->right) {
if (!root->right->left && !root->right->right && root->right->val == target)
root->right = nullptr;
}
// 注意如果 root 本身成了叶子节点并且和 target 相等, 那么返回 nullptr
return (!root->left && !root->right && root->val == target) ? nullptr : root;
}
public:
TreeNode* removeLeafNodes(TreeNode* root, int target) {
return postOrder(root, target);
}
};
C++ 实现 2
下面代码也是后序遍历, 而且更为简洁. 但实际上, 需要注意 deleteNode
的输入参数 root
此时是指针的引用!!! 那么在递归过程中, root = nullptr
会作用在树本身, 否则, 如果输入参数没有使用引用, 那么指针就是拷贝的, root = nullptr
这条命令不会作用在树中的节点上. 这个解法参考了 LeetCode Submission.
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
private:
void deleteNode(TreeNode* &root, int target) {
if (!root) return;
deleteNode(root->left, target);
deleteNode(root->right, target);
if (!root->left && !root->right && root->val == target) {
root = nullptr;
}
}
public:
TreeNode* removeLeafNodes(TreeNode* root, int target) {
deleteNode(root, target);
return root;
}
};