LeetCode 第23天

669. 修剪二叉搜索树
卡哥讲的两个遍历的方法不太听得懂,去题解找了一个和昨天的题类似的删除二叉树节点的方法,感觉好不错。但是还是挺难写出来的,需要判断的情况有点多,再加上递归,我有点泪目了。

class Solution {
public:
    // 感觉这个方法不错,抄了
    TreeNode* dfs(TreeNode* cur, int low, int high){
        // 返回
        if (cur == nullptr) return cur;
        // 遍历树
        cur->left = dfs(cur->left, low, high);
        cur->right = dfs(cur->right, low, high);
        // 删除节点
        if (cur->val < low || cur->val > high){
            // 叶子结点
            if (cur->left == nullptr && cur->right == nullptr) return nullptr;
            // 仅存在左子树
            else if (cur->left != nullptr && cur->right == nullptr) return cur->left;
            // 仅存在右子树
            else if (cur->left == nullptr && cur->right != nullptr) return cur->right;
            // 左右子树都存在时
            else {
                // 左子树接到右子树的最左节点
                TreeNode* tmp = cur->right;
                while (tmp->left) tmp = tmp->left;
                tmp->left = cur->left;
                // 返回右子树
                return cur->right;
            }
            
        }return cur;
    } 
    TreeNode* trimBST(TreeNode* root, int low, int high) {
        // 头一次见两个递归的代码,真的廷听看不懂的
        // if (root == nullptr) return root;
        // if (root->val < low){
        //     TreeNode* right = trimBST(root->right, low ,high);
        //     return right;
        // }
        // if (root->val > high){
        //     TreeNode* left = trimBST(root->left, low, high);
        //     return left;
        // }
        // root->left = trimBST(root->left, low, high);
        // root->right = trimBST(root->right, low, high);
        // return root;
        return dfs(root, low, high);
    }
};

108. 将有序数组转换为二叉搜索树
这题类似二分查找,归并排序的方法,先找到中间节点,然后两边的分别递归继续找,直到左大于右停止,当左等于右的时候可以继续,然后多递归一次最后返回唯一的节点。遍历过程中需要用当前的结点接住递归返回的左右孩子,是一个好理解且很不错的题目。

class Solution {
public:
    TreeNode* traversal(vector<int>& nums, int left, int right){
        // 递归终止条件变为左大于右,等于时可取,因为本题左闭右闭
        if (left > right) return nullptr;
        int mid = (left + right)/2;
        // 每一半数组选取中间节点(向下取整)建立新节点
        TreeNode* root = new TreeNode(nums[mid]);
        // 左边接住返回的节点
        root->left = traversal(nums, left, mid-1);
        // 右边接住返回的节点
        root->right = traversal(nums, mid+1, right);
        return root;
    }
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        return traversal(nums, 0 ,nums.size()-1);
    }
};

538. 把二叉搜索树转换为累加树

这题我还是比较自豪的,卡哥说可以用之前学过的双指针法,我就来自己尝试,发现二叉搜索树从右向左遍历就可以用前一个节点的值加上本节点的值得出结果,开心。递归边界什么的也比较常规,关键就是中序遍历。

class Solution {
public:
// 双指针法。yyds
    TreeNode* pre = nullptr;
    TreeNode* convertBST(TreeNode* root) {
        if (root == nullptr) return root;
        // 从右向左中序遍历,本节点的值就等于上一个节点的值加上本节点的值
        convertBST(root->right);
        if (pre != nullptr){
            root->val += pre->val;
        }
        pre = root;
        convertBST(root->left);
        // 结尾返回根节点
        return root;
    }
};

总结:二叉树已经刷完了,几乎所有题目都可以递归,也有少部分题目迭代比较简单。掌握递归传递参数、终止条件、递归体内处理逻辑、递归是否需要返回值等。二叉树的题目以前一直喜欢但又惧怕写递归,现在就是照葫芦画瓢写了一些题目,但是边摸索边前进,终究会有照亮的一天(大话)。

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值