代码随想录算法训练营day21

8 阅读3分钟

669修剪二叉搜索树 1.三步法递归 2.根据返回值调整策略 3.我们自己要学会回收内存,做一个合格的c++程序员

class Solution {
public:
    //为保证内存不泄露,设置删除二叉树的删除函数
void deleteBST(TreeNode* root) {
        if (root == nullptr) return;
        // 后序遍历:先删左右子树,再删当前节点(避免野指针)
        deleteBST(root->left);
        deleteBST(root->right);
        delete root;
    }

    TreeNode* trimBST(TreeNode* root, int low, int high) {
        if (root == nullptr) return root;

        // 情况1:当前节点值 < low → 仅右子树可能有效
        if (root->val < low) {
            // 优化:变量名改为validRight,贴合实际含义
            TreeNode* validRight = trimBST(root->right, low, high);
            deleteBST(root->left); // 删除当前节点+所有子树(左子树全无效)
            delete root;
            return validRight;
        }
        // 情况2:当前节点值 > high → 仅左子树可能有效
        else if (root->val > high) {
            // 优化:变量名改为validLeft,贴合实际含义
            TreeNode* validLeft = trimBST(root->left, low, high);
            deleteBST(root->right); // 删除当前节点+所有子树(右子树全无效)
            delete root;
            return validLeft;
        }
        // 情况3:当前节点有效 → 递归修剪左右子树并挂载
        else {
            root->left = trimBST(root->left, low, high);
            root->right = trimBST(root->right, low, high);
            return root;
        }
    }
};

108 将有序数组转换为平衡二叉树 1.需要理解平衡二叉树的性质和构造方法,采用二分取中值的递归方法不断以根节点构造树 2.要熟练掌握和理解递归三部曲,尤其时底层递归的返回条件,单层递归的执行逻辑 3.注意head+tail可能超出int值,所有要采用head+(tail-head)/2的方法求中值


class Solution {
public:
    //根据传入参数和返回值设置新的递归函数
    TreeNode* partsortedToBST(vector<int> & nums,int head,int tail){
        //递归底层的返回逻辑
        if(head>tail) return nullptr;
        //设置单层递归逻辑
        int mid=head+(tail-head)/2;//将区间中点设置为此次递归的根结点
        TreeNode* root=new TreeNode(nums[mid]);
        //递归设置root的左右孩子
        root->left=partsortedToBST(nums,head,mid-1);
        root->right=partsortedToBST(nums,mid+1,tail);
        return root;
    }
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        //采用递归方法构建二叉树,由于数组传入时有序,所以可以使用二分方式不断构建平衡二叉树
        //设置传入参数和返回值
        return partsortedToBST(nums,0,nums.size()-1);
    }
};

538 把二叉搜索树转换成累加树 实际时中序遍历的变体,使用特殊值记录就可以了。

递归版本


class Solution {
private: int sum=0;//用于记录遍历节点数值之和
public:
    void  sumcover(TreeNode* &root){
        //递归返回逻辑
        if(root==nullptr) return;
        //执行右中左的中序递归遍历
        sumcover(root->right);
        //对当前结点值进行覆盖
        root->val=root->val+sum;
        sum=root->val;
        //对左子树进行遍历
        sumcover(root->left);
    }
    TreeNode* convertBST(TreeNode* root) {
        //递归法,实际为右中左的中序遍历
        //不需要对原树结构额外操作,所以也不需要返回值,因此可以直接传入参数
        sumcover(root);
        return root;
    }
};

迭代版本

class Solution {
private: int sum=0;//用于记录遍历节点数值之和
public:
   
    TreeNode* convertBST(TreeNode* root) {
        //迭代版本
        if(root==nullptr) return root;//提前终止访问
        //设置栈存储需要访问的结点
        stack<TreeNode*> st;
        
        //执行迭代
        TreeNode* tmp=root;
        while(tmp!=nullptr||!st.empty()){
           
            if(tmp!=nullptr){//迭代至右侧结点  
                st.push(tmp);
                tmp=tmp->right;
            }
            else{//处理结点并赋值
             tmp=st.top();
             st.pop();
             tmp->val=tmp->val+sum;
             sum=tmp->val;
             tmp=tmp->left;
            }
        }

        return root;
    }
};