LeetCode Day23

63 阅读3分钟

669. 修剪二叉搜索树

给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在 唯一的答案 。 所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。

示例 1: 输入:root = [1,0,2], low = 1, high = 2 输出:[1,null,2] 示例 2: 输入:root = [3,0,4,null,2,null,null,1], low = 1, high = 3 输出:[3,2,null,1]

思路

主要思路是通过递归方式来修剪二叉搜索树(BST)。我们将从根节点开始,然后分别考虑以下几种情况:

  1. 节点为空:如果当前节点为空,那么直接返回 nullptr
  2. 节点值小于最小边界 **low**:这意味着该节点及其所有左子树节点都不在 [low, high] 范围内。因此,我们将修剪掉整个左子树,并递归地对右子树进行相同的操作。
  3. 节点值大于最大边界 high:与上一种情况相反,这意味着该节点及其所有右子树节点都不在 [low, high] 范围内。我们将修剪掉整个右子树,并递归地对左子树进行相同的操作。
  4. 节点值在 [low, high] 范围内:如果当前节点的值在这个范围内,那么这个节点是需要保留的。但是,它的左子树和右子树可能包含不在这个范围内的节点。因此,我们需要递归地对左子树和右子树进行修剪。

以上四种情况涵盖了所有可能的场景。通过递归地应用这些规则,我们最终将得到一个修剪后的树,该树的所有节点值都在 [low, high] 范围内,并且保留了原始树中节点的相对结构。

题解

/**
 * 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* trimBST(TreeNode* root, int low, int high) {
        // 基本情况:如果当前节点为空,则返回nullptr
        if (root == nullptr) {
            return nullptr;
        }

        // 如果当前节点的值小于最小边界low,那么它以及它的左子树都应该被修剪掉
        if (root->val < low) {
            return trimBST(root->right, low, high);
        }
        
        // 如果当前节点的值大于最大边界high,那么它以及它的右子树都应该被修剪掉
        if (root->val > high) {
            return trimBST(root->left, low, high);
        }
        
        // 如果当前节点的值在[low, high]范围内,那么递归修剪它的左子树和右子树
        root->left = trimBST(root->left, low, high);
        root->right = trimBST(root->right, low, high);
        
        // 返回修剪后的当前节点
        return root;
    }
};