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

669. 修剪二叉搜索树

题目链接:669. 修剪二叉搜索树

文档讲解:代码随想录/修剪二叉搜索树

视频讲解:视频讲解-修剪二叉搜索树

状态:已完成(1遍)

解题过程 

看到题目的第一想法

 感觉还是删除二叉树的变种。我想着每层递归内对当前节点值进行判断,如果在区间内,则左右子节点继续递归下去;如果比最小值还小,那么这个节点的整个左子树肯定没用了;同理如果比最大值还大,这个节点的整个右子树肯定没用了;

手搓代码如下:

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @param {number} low
 * @param {number} high
 * @return {TreeNode}
 */
var trimBST = function(root, low, high) {
    let deleteNode = function(node){
        if(node == null)return null;
        if(node.val>=low&&node.val<=high){//在这之间的话,左右还是正常的递归下去
            node.left = deleteNode(node.left);
            node.right = deleteNode(node.right);
            return node;
        }else if(node.val<low){//比最低值还小,说明这个节点的左节点也没用了
            node = deleteNode(node.right);
            return node;
        }else if(node.val>high){//比最大值还大,说明这个节点的右节点也没用了
            node = deleteNode(node.left);
            return node;
        }
    }
    return deleteNode(root);
};

提交没有问题。

看完代码随想录之后的想法 

讲解代码的思路跟我差不多,区别可能就在他有明确的当前递归层的处理逻辑,而我是直接融入终止递归条件中了。

讲解代码如下:

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @param {number} low
 * @param {number} high
 * @return {TreeNode}
 */
var trimBST = function (root,low,high) {
    if(root === null) {
        return null;
    }
    if(root.val < low) {
        let right = trimBST(root.right, low, high);
        return right;
    }
    if(root.val > high) {
        let left = trimBST(root.left, low, high);
        return left;
    }
    root.left = trimBST(root.left, low, high);
    root.right = trimBST(root.right, low, high);
    return root;
 }

总结

相比于删除某个节点来说,节点若不符合区间的话处理起来方便很多。


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

题目链接:108.将有序数组转换为二叉搜索树

文档讲解:代码随想录/将有序数组转换为二叉搜索树

视频讲解:视频讲解-将有序数组转换为二叉搜索树

状态:已完成(1遍)

解题过程  

看到题目的第一想法

很眼熟的题目,之前有道最大二叉树也是将一个数组中最大的数字提取出来作为当前节点,印象很深的是当时我自己递归传参传的是一个新数组,卡哥给的解法是传递两个索引。那么这道题既然要求要构建一个平衡二叉搜索树,那么我每次取的节点值都一定要在当前数组的中间。

手搓代码如下:

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {number[]} nums
 * @return {TreeNode}
 */
var sortedArrayToBST = function (nums) {
    const balance = function (left, right) {
        if (left > right) return null;
        else {
            let mid = Math.round((left + right) / 2);
            let node = new TreeNode(nums[mid]);
            node.left = balance(left,mid-1);
            node.right = balance(mid+1,right);
            return node;
        }
    }
    return balance(0,nums.length-1);
};

提交没有问题。 

 看完代码随想录之后的想法 

讲解代码和我几乎一模一样,惊了。略有成就感。

总结

给数组构造二叉树,可以在传参时只传索引,不传数组来提高速度。


 

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

题目链接:538.把二叉搜索树转换为累加树

文档讲解:代码随想录/把二叉搜索树转换为累加树

视频讲解:视频讲解-把二叉搜索树转换为累加树

状态:已完成(1遍)

解题过程  

看到题目的第一想法

读题都没读懂。。。什么叫使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和???

 看完代码随想录之后的想法 

讲解之后才知道累加树的具体含义,自己的节点值加上比自己节点值大的所有节点值就是自己的新节点值。

看了讲解手搓代码如下:

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {TreeNode}
 */
var convertBST = function (root) {
    let pre = 0;
    const addTree = function (node) {
        if (node == null) return;
        addTree(node.right);
        node.val += pre;
        pre = node.val;
        addTree(node.left);
        return node;
    }
    return addTree(root);
};

没想到提交214/215。。原来是空数组的情况下我输出的是undefined。看了眼文字讲解发现最后输出写的略有区别。

文字讲解代码如下:

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {TreeNode}
 */
var convertBST = function (root) {
    let pre = 0;
    const addTree = function (node) {
        if (node == null) return;
        addTree(node.right);
        node.val += pre;
        pre = node.val;
        addTree(node.left);
        return node;
    }
    addTree(root);
    return root;
};

这样就没有问题了。 

 

总结

 这道题的后序并不是机械的左右中,而是为了迎合题目的要求,从右往左,用的右中左。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
代码随想录算法训练营是一个优质的学习和讨论平台,提供了丰富的算法训练内容和讨论交流机会。在训练营中,学员们可以通过观看视频讲解来学习算法知识,并根据讲解内容进行刷题练习。此外,训练营还提供了刷题建议,例如先看视频、了解自己所使用的编程语言、使用日志等方法来提高刷题效果和语言掌握程度。 训练营中的讨论内容非常丰富,涵盖了各种算法知识点和解题方法。例如,在第14训练营中,讲解了二叉的理论基础、递归遍历、迭代遍历和统一遍历的内容。此外,在讨论中还分享了相关的博客文章和配图,帮助学员更好地理解和掌握二叉的遍历方法。 训练营还提供了每日的讨论知识点,例如在第15的讨论中,介绍了层序遍历的方法和使用队列来模拟一层一层遍历的效果。在第16的讨论中,重点讨论了如何进行调试(debug)的方法,认为掌握调试技巧可以帮助学员更好地解决问题和写出正确的算法代码。 总之,代码随想录算法训练营是一个提供优质学习和讨论环境的平台,可以帮助学员系统地学习算法知识,并提供了丰富的讨论内容和刷题建议来提高算法编程能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [代码随想录算法训练营每日精华](https://blog.csdn.net/weixin_38556197/article/details/128462133)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值