代码随想录算法训练营第二十三天|669. 修剪二叉搜索树、108.将有序数组转换为二叉搜索树、538.把二叉搜索树转换为累加树

LeetCode 669 修剪二叉搜索树

题目链接:https://leetcode.cn/problems/trim-a-binary-search-tree/

思路:

如果当前父节点值小于最小边界,那么其左子树可以直接完全修剪掉,右子树有可能存在符合条件的值,所以要继续往右遍历;同理,如果当前父节点值大于最大边界,那么其右子树可以直接完全修剪掉,左子树有可能存在符合条件的值,所以要继续往左遍历

代码:

  • 递归法

/**
 * 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) {
        if(!root)   return nullptr;
        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;
    }
};

总结

修剪的思路是想到了的,只不过写的时候写的和昨天删除节点的值相类似,没有想明白遇到了父节点值该如何一直向左或向右遍历,将整棵树遍历完。

LeetCode 108 将有序数组转换为二叉搜索树

题目链接:https://leetcode.cn/problems/convert-sorted-array-to-binary-search-tree/

思路:

类似用后序与中序构建二叉树,不过比那道题还要简单。因为是有序数组,所以节点元素必然是中间位置的值,然后再左右划分数组即可。注:如果数组大小为偶数,那么中间值会有两个,这样就会出现两种情况,这也是题目中说答案不唯一的原因。

代码:

  • 创建新数组法

/**
 * 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* sortedArrayToBST(vector<int>& nums) {
        // 1、终止条件
        if(nums.empty())
            return nullptr;

        // 2、寻找节点元素
        int index = nums.size()/2;
        int rootval = nums[index];
        TreeNode *root = new TreeNode(rootval);

        // 处理叶子节点
        if(nums.size()==1)
            return root;

        // 3、切割有序数组
        vector<int>left(nums.begin(),nums.begin()+index);
        vector<int>right(nums.begin()+index+1,nums.end());

        // 4、递归处理左右子树
        root->left = sortedArrayToBST(left);
        root->right = sortedArrayToBST(right);

        return root;
    }
};
  • 下标法

/**
 * 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* sortedArrayToBST(vector<int>& nums) {
        TreeNode *root = traversal(nums,0,nums.size());
        return root;
    }

    TreeNode* traversal(vector<int>& nums,int left,int right)
    {
        if(left>=right)  return nullptr;
        int mid = left+((right-1-left)/2);  // 避免越界
        TreeNode *root = new TreeNode(nums[mid]);
        root->left = traversal(nums,left,mid); 
        root->right = traversal(nums,mid+1,right);
        return root;
    }

};

总结

比昨天的中序与后序构造二叉树简单,可以自己完整写出来

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

题目链接:https://leetcode.cn/problems/convert-bst-to-greater-tree/

思路:

累加的意思是:倒序将二叉树的各节点值累加起来

从最右边节点8开始,然后到上一个节点7,要累加8,所以变成了15,然后到节点6......,依次类推。

遍历方式:

代码:

  • 双指针法-自写

/**
 * 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 *pre = nullptr;
    TreeNode* convertBST(TreeNode* root) {
        if(!root)   return nullptr;

        root->right = convertBST(root->right);

        if(pre)
        {
            root->val += pre->val;
        }
        pre = root;

        root->left = convertBST(root->left);

        return root;

    }
};
  • 卡哥代码

/**
 * 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:
    int pre = 0; // 记录前一个节点的值
    TreeNode* convertBST(TreeNode* root) {
        traversal(root);
        return root;
    }

    void traversal(TreeNode *cur)
    {
        if(!cur)    return ;
        
        traversal(cur->right);

        cur->val += pre;
        pre = cur->val;

        traversal(cur->left);
    }
};

总结

一开始没理解题目什么意思,看了视频前半段讲解才理解题目意思,然后很轻松的就写出来了代码。

今日总结:

二叉树到此终于完结了,二叉树章节题目很多,有很多题目很难,没接触过,现在回想起来再重新写,估计也很难写出来,在后面做题的时候要一边做一边复习一下之前写过的题目。一刷肯定不够的,二刷搞起,希望有时间可以三刷。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值