1325. Delete Leaves With a Given Value**

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;
    }
};
发布了352 篇原创文章 · 获赞 7 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Eric_1993/article/details/104564761