给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。
    一般来说,删除节点可分为两个步骤:

    1. 首先找到需要删除的节点;
    2. 如果找到了,删除它。

    说明: 要求算法时间复杂度为 O(h),h 为树的高度。
    示例:

    1. root = [5,3,6,2,4,null,7]
    2. key = 3
    3. 5
    4. / \
    5. 3 6
    6. / \ \
    7. 2 4 7
    8. 给定需要删除的节点值是 3,所以我们首先找到 3 这个节点,然后删除它。
    9. 一个正确的答案是 [5,4,6,2,null,null,7], 如下图所示。
    10. 5
    11. / \
    12. 4 6
    13. / \
    14. 2 7
    15. 另一个正确答案是 [5,2,6,null,4,null,7]。
    16. 5
    17. / \
    18. 2 6
    19. \ \
    20. 4 7
    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
     *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
     *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
     * };
     */
    class Solution {
    public:
        TreeNode* deleteNode(TreeNode* root, int key) {
            if(root == nullptr) return root;
    
            if(root->val == key){
                if(root->left != nullptr && root->right != nullptr){
                    TreeNode* temp = root->right;
                    while(temp->left != nullptr){
                        temp = temp->left;
                    }               
                    root->right = deleteNode(root->right, temp->val);
                    root->val = temp->val;
                }else{
    
                    if(root->left == nullptr){
                        return root->right;
                    }else{
                        return root->left;
                    }
                }
            }else if(root->val < key){
                root->right = deleteNode(root->right, key);
            }else{
                root->left = deleteNode(root->left, key);
            }
            return root;       
        }
    };